host.go

v0.3.0
Doc Versions Source
1
package legatus
2
3
// Host is a single SSH target the orchestrator can act on.
4
type Host struct {
5
	Name   string
6
	Addr   string
7
	Port   int
8
	User   string
9
	Tags   []string
10
	Groups []string
11
	Vars   map[string]any
12
}
13
14
// Selector reports whether a host belongs to a selection. Selectors are pure
15
// predicates over a Host so they compose without reaching back into Inventory.
16
type Selector func(*Host) bool
17
18
// ByName selects hosts whose Name is in names.
19
func ByName(names ...string) Selector {
20
	set := make(map[string]struct{}, len(names))
21
	for _, n := range names {
22
		set[n] = struct{}{}
23
	}
24
	return func(h *Host) bool {
25
		_, ok := set[h.Name]
26
		return ok
27
	}
28
}
29
30
// ByTag selects hosts carrying any of the given tags.
31
func ByTag(tags ...string) Selector {
32
	return func(h *Host) bool {
33
		return containsAny(h.Tags, tags)
34
	}
35
}
36
37
// InGroup selects hosts that are members of the named group.
38
func InGroup(group string) Selector {
39
	return func(h *Host) bool {
40
		return containsAny(h.Groups, []string{group})
41
	}
42
}
43
44
func containsAny(have, want []string) bool {
45
	for _, w := range want {
46
		for _, h := range have {
47
			if h == w {
48
				return true
49
			}
50
		}
51
	}
52
	return false
53
}
54
55
// Inventory is the set of hosts an orchestration runs against.
56
type Inventory struct {
57
	hosts []*Host
58
}
59
60
// NewInventory builds an inventory from the given hosts.
61
func NewInventory(hosts ...*Host) *Inventory {
62
	inv := &Inventory{}
63
	inv.hosts = append(inv.hosts, hosts...)
64
	return inv
65
}
66
67
// Add appends a host to the inventory.
68
func (inv *Inventory) Add(h *Host) { inv.hosts = append(inv.hosts, h) }
69
70
// Hosts returns the hosts matching every selector (logical AND). With no
71
// selectors it returns all hosts.
72
func (inv *Inventory) Hosts(sel ...Selector) []*Host {
73
	var out []*Host
74
	for _, h := range inv.hosts {
75
		if matchAll(h, sel) {
76
			out = append(out, h)
77
		}
78
	}
79
	return out
80
}
81
82
// Group returns the hosts that are members of the named group.
83
func (inv *Inventory) Group(name string) []*Host {
84
	return inv.Hosts(InGroup(name))
85
}
86
87
func matchAll(h *Host, sel []Selector) bool {
88
	for _, s := range sel {
89
		if !s(h) {
90
			return false
91
		}
92
	}
93
	return true
94
}
95

Source Files