Add mutual exclusivity to manager host selectors
Using a label selector and name when creating a manager will produce the union of all host documents that match the criteria. While this is not inherently a problem, it's not expected behavior. This change makes using the label selector and name property mutually exclusive. When creating a manger using both selectors, the manager will contain the intersection of hosts, rather than the union. Change-Id: I791e0460cea2ae3d60ea2cc24f900b925c36d9af Signed-off-by: Drew Walters <andrew.walters@att.com>
This commit is contained in:
parent
d126615f8b
commit
bbb823306d
@ -78,15 +78,18 @@ func ByLabel(label string) HostSelector {
|
|||||||
return document.ErrDocNotFound{Selector: selector}
|
return document.ErrDocNotFound{Selector: selector}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var matchingHosts []baremetalHost
|
||||||
for _, doc := range docs {
|
for _, doc := range docs {
|
||||||
host, err := newBaremetalHost(mgmtCfg, doc, docBundle)
|
host, err := newBaremetalHost(mgmtCfg, doc, docBundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Hosts = append(a.Hosts, host)
|
matchingHosts = append(matchingHosts, host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.Hosts = reconcileHosts(a.Hosts, matchingHosts...)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +108,7 @@ func ByName(name string) HostSelector {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Hosts = append(a.Hosts, host)
|
a.Hosts = reconcileHosts(a.Hosts, host)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -202,3 +205,25 @@ func newBaremetalHost(mgmtCfg config.ManagementConfiguration,
|
|||||||
|
|
||||||
return host, nil
|
return host, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reconcileHosts produces the intersection of two baremetal host arrays.
|
||||||
|
func reconcileHosts(existingHosts []baremetalHost, newHosts ...baremetalHost) []baremetalHost {
|
||||||
|
if len(existingHosts) == 0 {
|
||||||
|
return newHosts
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a map of host document names for efficient filtering
|
||||||
|
hostMap := make(map[string]bool)
|
||||||
|
for _, host := range existingHosts {
|
||||||
|
hostMap[host.HostName] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
var reconciledHosts []baremetalHost
|
||||||
|
for _, host := range newHosts {
|
||||||
|
if _, exists := hostMap[host.HostName]; exists {
|
||||||
|
reconciledHosts = append(reconciledHosts, host)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reconciledHosts
|
||||||
|
}
|
||||||
|
@ -95,6 +95,26 @@ func TestNewManagerMultipleNodes(t *testing.T) {
|
|||||||
assert.Equal(t, "node-master-2", manager.Hosts[1].NodeID())
|
assert.Equal(t, "node-master-2", manager.Hosts[1].NodeID())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewManagerMultipleSelectors(t *testing.T) {
|
||||||
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
|
|
||||||
|
manager, err := NewManager(settings, config.BootstrapPhase, ByName("master-1"),
|
||||||
|
ByLabel("airshipit.org/test-node=true"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(manager.Hosts))
|
||||||
|
|
||||||
|
assert.Equal(t, "node-master-1", manager.Hosts[0].NodeID())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewManagerMultipleSelectorsNoMatch(t *testing.T) {
|
||||||
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
|
|
||||||
|
manager, err := NewManager(settings, config.BootstrapPhase, ByName("master-2"),
|
||||||
|
ByLabel(document.EphemeralHostSelector))
|
||||||
|
require.Equal(t, 0, len(manager.Hosts))
|
||||||
|
assert.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestNewManagerByNameNoHostFound(t *testing.T) {
|
func TestNewManagerByNameNoHostFound(t *testing.T) {
|
||||||
settings := initSettings(t, withTestDataPath("base"))
|
settings := initSettings(t, withTestDataPath("base"))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user