Skip to content

Commit

Permalink
add support of tags in inventory or hosts and match as a potential ta…
Browse files Browse the repository at this point in the history
…rget
  • Loading branch information
umputun committed May 2, 2023
1 parent acaca3d commit e4d2a04
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 14 deletions.
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ Targets contains environments each of which represents a set of hosts, for examp
```yaml
targets:
prod:
hosts: [{host: "h1.example.com", user: "test"}, {"h2.example.com", "port": 2222}]
hosts: [{host: "h1.example.com", user: "test"}, {"h2.example.com", "port": 2222, name: "h2"}]
staging:
groups: ["staging"]
dev:
Expand All @@ -237,6 +237,19 @@ There are several ways to override or alter the target defined in the playbook f
- `--user` set the ssh user to run the playbook on remote hosts. Example: `--user=test`.
- `--key` set the ssh key to run the playbook on remote hosts. Example: `--key=/path/to/key`.

### Target selection

The target selection is done in the following order:

- if `--target` is set, it will be used.
- first Spot will try to match on target name in the playbook file.
- if no match found, Spot will try to match on group name in the inventory file.
- if no match found, Spot will try to match on tags in the inventory file.
- if no match found, Spot will try to match on host name in the inventory file.
- if no match found, Spot will try to match on host address in the playbook file.
- if no match found, Spot will use it as a host name.
- if `--target` is not set, Spot will assume the `default` target.

### Inventory

The inventory file is a simple yml what can represent a list of hosts or a list of groups with hosts. In case if both groups and hosts defined, the hosts will be merged with groups and will add a new group named `hosts`.
Expand All @@ -248,7 +261,7 @@ This is an example of the inventory file with groups
```yaml
groups:
dev:
- {host: "h1.example.com", name: "h1"}
- {host: "h1.example.com", name: "h1", tags:["us-east1", "vpc-1234567"]}
- {host: "h2.example.com", port: 2233, name: "h2"}
- {host: "h3.example.com", user: "user1"}
- {host: "h4.example.com", user: "user2", name: "h4"}
Expand All @@ -257,17 +270,21 @@ groups:
- {host: "h6.example.com", user: "user3", name: "h6"}
```

In case if port not defined, the default port 22 will be used. If user not defined, the playbook's user will be used.
- host: the host name or IP address of the remote host.
- port: the ssh port of the remote host. Optional, default is 22.
- user: the ssh user of the remote host. Optional, default is the user defined in the playbook file or `--user` flag.
- name: the name of the remote host. Optional.
- tags: the list of tags of the remote host. Optional.

note: the `name` field is optional and used only to make reports/log more readable.
In case if port not defined, the default port 22 will be used. If user not defined, the playbook's user will be used.

This is an example of the inventory file with hosts only (no groups)

```yaml
hosts:
- {host: "hh1.example.com", name: "hh1"}
- {host: "hh2.example.com", port: 2233, name: "hh2", user: "user1"}
- {host: "h2.example.com", port: 2233, name: "h2"}
- {host: "h2.example.com", port: 2233, name: "h2", tags:["us-east1", "vpc-1234567"]}
- {host: "h3.example.com", user: "user1", name: "h3"}
- {host: "h4.example.com", user: "user2", name: "h4"}
```
Expand Down
23 changes: 19 additions & 4 deletions app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ type Cmd struct {

// Destination defines destination info
type Destination struct {
Name string `yaml:"name"`
Host string `yaml:"host"`
Port int `yaml:"port"`
User string `yaml:"user"`
Name string `yaml:"name"`
Host string `yaml:"host"`
Port int `yaml:"port"`
User string `yaml:"user"`
Tags []string `yaml:"tags"`
}

// CopyInternal defines copy command, implemented internally
Expand Down Expand Up @@ -284,6 +285,20 @@ func (p *PlayBook) TargetHosts(name string) ([]Destination, error) {
return res, nil
}

// try as a tag in inventory
for _, h := range p.inventory.Groups["all"] {
if len(h.Tags) == 0 {
continue
}
for _, t := range h.Tags {
if strings.EqualFold(t, name) {
res := []Destination{h}
res[0].User = userOverride(h.User)
return res, nil
}
}
}

// try as single host name in inventory
for _, h := range p.inventory.Groups["all"] {
if strings.EqualFold(h.Name, name) {
Expand Down
15 changes: 10 additions & 5 deletions app/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,14 @@ func TestTargetHosts(t *testing.T) {
"all": {
{Host: "host1.example.com", Port: 22, User: "user1"},
{Host: "host2.example.com", Port: 22, User: "defaultuser", Name: "host2"},
{Host: "host3.example.com", Port: 22, User: "defaultuser", Name: "host3"},
{Host: "host3.example.com", Port: 22, User: "defaultuser", Name: "host3", Tags: []string{"tag1", "tag2"}},
},
"group1": {
{Host: "host2.example.com", Port: 2222, User: "defaultuser", Name: "host2"},
},
},
Hosts: []Destination{
{Host: "host3.example.com", Port: 22, Name: "host3"},
{Host: "host3.example.com", Port: 22, Name: "host3", Tags: []string{"tag1", "tag2"}},
},
},
}
Expand All @@ -367,14 +367,19 @@ func TestTargetHosts(t *testing.T) {
[]Destination{{Host: "host2.example.com", Port: 2222, User: "defaultuser", Name: "host2"}},
false,
},
{
"target as a tag from inventory", "tag2", nil,
[]Destination{{Host: "host3.example.com", Port: 22, User: "defaultuser", Name: "host3", Tags: []string{"tag1", "tag2"}}},
false,
},
{
"target as single host by name from inventory", "host3", nil,
[]Destination{{Host: "host3.example.com", Port: 22, User: "defaultuser", Name: "host3"}},
[]Destination{{Host: "host3.example.com", Port: 22, User: "defaultuser", Name: "host3", Tags: []string{"tag1", "tag2"}}},
false,
},
{
"target as single host from inventory", "host3.example.com", nil,
[]Destination{{Host: "host3.example.com", Port: 22, User: "defaultuser", Name: "host3"}},
[]Destination{{Host: "host3.example.com", Port: 22, User: "defaultuser", Name: "host3", Tags: []string{"tag1", "tag2"}}},
false,
},
{
Expand All @@ -394,7 +399,7 @@ func TestTargetHosts(t *testing.T) {
},
{
"user override", "host3", &Overrides{User: "overriddenuser"},
[]Destination{{Host: "host3.example.com", Port: 22, User: "overriddenuser", Name: "host3"}},
[]Destination{{Host: "host3.example.com", Port: 22, User: "overriddenuser", Name: "host3", Tags: []string{"tag1", "tag2"}}},
false,
},
}
Expand Down

0 comments on commit e4d2a04

Please sign in to comment.