Skip to content

Commit

Permalink
add runtime SPOT_REMOTE_ADDR and SPOT_REMOTE_PORT
Browse files Browse the repository at this point in the history
Those variables are split from `hostAddr` to `SPOT_REMOTE_ADDR` and `SPOT_REMOTE_PORT`. The documentation has also been updated to reflect these changes.
  • Loading branch information
umputun committed Apr 5, 2024
1 parent cdc6bbe commit fee8f83
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 11 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions pkg/runner/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"log"
"math"
mr "math/rand"
"net"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -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 {
Expand Down
31 changes: 28 additions & 3 deletions pkg/runner/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
43 changes: 36 additions & 7 deletions site/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
----

<div align="center">
Expand Down Expand Up @@ -141,8 +141,8 @@ Spot supports the following command-line options:
- `-k`, `--key=`: Specifies the SSH key for connecting to remote hosts. Overrides the key defined in the playbook file.
- `-s`, `--skip=`: Skips the specified commands during the task execution. Providing the `-s` flag multiple times with different command names skips multiple commands.
- `-o`, `--only=`: Runs only the specified commands during the task execution. Providing the `-o` flag multiple times with different command names runs only multiple commands.
- `-e`, `--env=`: Sets the environment variables to be used during the task execution. Providing the `-e` flag multiple times with different environment variables sets multiple environment variables, e.g., `-e VAR1:VALUE1 -e VAR2:VALUE2`.
- `-E`, `--env-file=`: Sets the environment variables from the file to be used during the task execution. The default is env.yml. Can also be set with the environment variable `SPOT_ENV_FILE`.
- `-e`, `--env=`: Sets the environment variables to be used during the task execution. Providing the `-e` flag multiple times with different environment variables sets multiple environment variables, e.g., `-e VAR1:VALUE1 -e VAR2:VALUE2`. Values could be taken from the OS environment variables as well, e.g., `-e VAR1:$ENV_VAR1` or `-e VAR1:${ENV_VAR1}`.
- `-E`, `--env-file=`: Sets the environment variables from the file to be used during the task execution. The file can have values from the OS environment variables as well. The default is env.yml. Can also be set with the environment variable `SPOT_ENV_FILE`.
- `--no-color`: disable the colorized output. It can also be set with the environment variable `SPOT_NO_COLOR`.
- `--dry`: Enables dry-run mode, which prints out the commands to be executed without actually executing them.
- `-v`, `--verbose`: Enables verbose mode, providing more detailed output and error messages during the task execution.
Expand Down Expand Up @@ -452,6 +452,17 @@ example setting `ignore_errors`, `no_auto` and `only_on` options:
options: {ignore_errors: true, no_auto: true, only_on: [host1, host2]}
```

The same options can be set for the whole task as well. In this case, the options will be applied to all commands in the task but can be overridden for a specific command. Pls note: the command option cannot reset the boolean options that were set for the task. This limitation is due to the way the default values are set.

```yaml
- name: deploy-things
on_error: "curl -s localhost:8080/error?msg={SPOT_ERROR}" # call hook on error
options: {ignore_errors: true, no_auto: true, only_on: [host1, host2]}
commands:
- name: wait
script: sleep 5s
```

### Command conditionals

`cond`: defines a condition for the command to be executed. The condition is a valid shell command that will be executed on the remote host(s) and if it returns 0, the primary command will be executed. For example, `cond: "test -f /tmp/foo"` will execute the primary script command only if the file `/tmp/foo` exists. The condition can be reversed by adding `!` prefix, i.e. `! test -f /tmp/foo` will pass only if the file `/tmp/foo` doesn't exist.
Expand Down Expand Up @@ -766,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.
Expand Down Expand Up @@ -825,6 +838,22 @@ tasks:

In this case secrets for keys `user`, `password` and `token` will be read from the secrets provider, decrypted at runtime, and passed to the command in the environment. Please note: if a user runs `spot` with the `--verbose` or `--dbg` flag, the secrets will be replaced with `****` in the output. This is done to prevent secrets from being displayed or logged.


Sometimes, users may want to use the same set of secrets in multiple commands. To avoid repeating the secrets in each command, users can set `secrets` at the task level, as shown in the following example:

```yaml
tasks:
- name: access sensitive data
commands:
- name: read api response
script: |
curl -s -u ${user}:${password} https://api.example.com
curl https://api.example.com -H "Authorization: Bearer ${token}"
options:
secrets: [user, password, token]
```


### Built-in Secrets Provider

Spot includes a built-in secrets provider that can be used to store secrets in SQLite, MySQL, or Postgresql databases. The provider can be configured using the following command line options or environment variables:
Expand Down

0 comments on commit fee8f83

Please sign in to comment.