diff --git a/README.md b/README.md index d72454d5..f1d510a2 100644 --- a/README.md +++ b/README.md @@ -777,7 +777,9 @@ _for more info see [go templates](https://pkg.go.dev/text/template)_ Spot supports runtime variables that can be used in the playbook file. The following variables are supported: -- `{SPOT_REMOTE_HOST}`: The remote hostname or IP address. +- `{SPOT_REMOTE_HOST}`: The remote hostname or IP address with port. +- `{SPOT_REMOTE_ADDR}`: The remote hostname or IP address. +- `{SPOT_REMOTE_PORT}`: The remote port. - `{SPOT_REMOTE_NAME}`: The remote custom name, set in inventory or playbook as `name`. - `{SPOT_REMOTE_USER}`: The remote username. - `{SPOT_COMMAND}`: The command name. diff --git a/pkg/runner/commands.go b/pkg/runner/commands.go index 8c5ea275..aeb26bd5 100644 --- a/pkg/runner/commands.go +++ b/pkg/runner/commands.go @@ -10,6 +10,7 @@ import ( "log" "math" mr "math/rand" + "net" "os" "path/filepath" "strings" @@ -489,6 +490,16 @@ func (tm *templater) apply(inp string) string { res = apply(res, "SPOT_REMOTE_USER", tm.task.User) res = apply(res, "SPOT_TASK", tm.task.Name) + // split hostAddr to SPOT_REMOTE_ADDR and SPOT_REMOTE_PORT + host, port, err := net.SplitHostPort(tm.hostAddr) + if err == nil { + res = apply(res, "SPOT_REMOTE_ADDR", host) + res = apply(res, "SPOT_REMOTE_PORT", port) + } else { + res = apply(res, "SPOT_REMOTE_ADDR", tm.hostAddr) + res = apply(res, "SPOT_REMOTE_PORT", "22") // set to default ssh port + } + if tm.err != nil { res = apply(res, "SPOT_ERROR", tm.err.Error()) } else { diff --git a/pkg/runner/commands_test.go b/pkg/runner/commands_test.go index ba42e09a..88abc74c 100644 --- a/pkg/runner/commands_test.go +++ b/pkg/runner/commands_test.go @@ -28,15 +28,40 @@ func Test_templaterApply(t *testing.T) { expected string }{ { - name: "all_variables", - inp: "${SPOT_REMOTE_HOST}:${SPOT_REMOTE_USER}:${SPOT_COMMAND}:{SPOT_REMOTE_NAME}", + name: "all variables, hostAddr without port", + inp: "${SPOT_REMOTE_HOST} ${SPOT_REMOTE_USER} ${SPOT_COMMAND} {SPOT_REMOTE_NAME} " + + "{SPOT_REMOTE_ADDR} {SPOT_REMOTE_PORT}", tmpl: templater{ hostAddr: "example.com", hostName: "example", command: "ls", task: &config.Task{Name: "task1", User: "user"}, }, - expected: "example.com:user:ls:example", + expected: "example.com user ls example example.com 22", + }, + { + name: "all variables, hostAddr with port", + inp: "${SPOT_REMOTE_HOST} ${SPOT_REMOTE_USER} ${SPOT_COMMAND} {SPOT_REMOTE_NAME} " + + "{SPOT_REMOTE_ADDR} {SPOT_REMOTE_PORT}", + tmpl: templater{ + hostAddr: "example.com:22022", + hostName: "example", + command: "ls", + task: &config.Task{Name: "task1", User: "user"}, + }, + expected: "example.com:22022 user ls example example.com 22022", + }, + { + name: "all variables, hostAddr ipv6 with port", + inp: "${SPOT_REMOTE_HOST} ${SPOT_REMOTE_USER} ${SPOT_COMMAND} {SPOT_REMOTE_NAME} " + + "{SPOT_REMOTE_ADDR} {SPOT_REMOTE_PORT}", + tmpl: templater{ + hostAddr: "[2001:db8::1]:22022", + hostName: "example", + command: "ls", + task: &config.Task{Name: "task1", User: "user"}, + }, + expected: "[2001:db8::1]:22022 user ls example 2001:db8::1 22022", }, { name: "no_variables", diff --git a/site/docs/index.md b/site/docs/index.md index b450822d..a10057e2 100644 --- a/site/docs/index.md +++ b/site/docs/index.md @@ -9,21 +9,21 @@ Spot is a powerful and easy-to-use tool for effortless deployment and configurat ## Features - Define [tasks](#tasks-and-commands) with a list of [commands](#command-types) and the list of [target hosts](#targets). -- Support for remote hosts specified directly or through [inventory](#inventory) files/URLs. +- Support for remote hosts specified directly or through [inventory](#inventory) files or URLs. - Everything can be defined in a [simple YAML](#full-playbook-example) or TOML file. - Run [scripts](#script-execution) on remote hosts and the localhost. - Built-in [commands](#command-types): script, copy, sync, delete, echo, and wait. -- [Concurrent](#rolling-updates) execution of task on multiple hosts. +- [Concurrent](#rolling-updates) execution of a task on multiple hosts. - Ability to wait for a specific condition before executing the next command. - Customizable environment variables. -- Support for [secrets](#secrets) stored in the [built-in](#built-in-secrets-provider) secrets storage, [Vault](#hashicorp-vault-secrets-provider) or [AWS Secrets Manager](#aws-secrets-manager-secrets-provider). +- Support for [secrets](#secrets) stored in the [built-in](#built-in-secrets-provider) secrets storage, [Vault](#hashicorp-vault-secrets-provider), [ansible vault](#ansible-vault-secrets-provider) or [AWS Secrets Manager](#aws-secrets-manager-secrets-provider). - Ability to [override](#command-options) list of destination hosts, ssh username and ssh key file. - Skip or execute only specific commands. - Catch errors and execute a command hook on the local host. - Debug mode to print out the commands to be executed, the output of the commands, and all the other details. - Dry-run mode to print out the commands to be executed without executing them. - [Ad-hoc mode](#ad-hoc-commands) to execute a single command on a list of hosts. -- A [single binary](https://github.com/umputun/spot/releases) with no dependencies. +- A [single binary](https://github.com/umputun/spot/releases) with no external dependencies. ----