Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
dist
# Our compiled binary
/cloud-init-server

.omo/
graphify-out/cache/
23 changes: 23 additions & 0 deletions internal/smdclient/FakeSMDClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/rs/zerolog/log"

base "github.com/Cray-HPE/hms-base"
"github.com/OpenCHAMI/smd/v2/pkg/sm"

"github.com/OpenCHAMI/cloud-init/pkg/cistore"
)
Expand Down Expand Up @@ -288,6 +289,28 @@ func (f *FakeSMDClient) PopulateNodes() {

// ***** Simulated SMD Client functions. Not part of the SMDClientInterface *****

// ListMemberships returns memberships derived from the simulator's group state.
func (f *FakeSMDClient) ListMemberships() []sm.Membership {
memberships := make([]sm.Membership, 0, len(f.rosetta_mapping))
for _, component := range f.rosetta_mapping {
groupLabels := make([]string, 0)
for group, componentIDs := range f.groups {
for _, componentID := range componentIDs {
if componentID == component.ComponentID {
groupLabels = append(groupLabels, group)
break
}
}
}
memberships = append(memberships, sm.Membership{
ID: component.ComponentID,
GroupLabels: groupLabels,
PartitionName: "",
})
}
return memberships
}

// AddNodeToInventory adds a node to the inventory. This is not part of the SMDClient Interface and only useful as part of the simulator
func (f *FakeSMDClient) AddNodeToInventory(node cistore.OpenCHAMIComponent) error {
log.Debug().Msgf("FakeSMDClient: AddNodeToInventory(%s)", node.ID)
Expand Down
51 changes: 51 additions & 0 deletions internal/smdclient/FakeSMDClient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import (
"net"
"strings"
"testing"

"github.com/OpenCHAMI/smd/v2/pkg/sm"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestIncrementXname(t *testing.T) {
Expand Down Expand Up @@ -130,3 +134,50 @@ func TestNewFakeSMDClient(t *testing.T) {
t.Errorf("expected 9 components in io group, got %d", len(client.groups["io"]))
}
}

func TestFakeSMDClientListMemberships(t *testing.T) {
client := NewFakeSMDClient("fake", 12)
representativeIDs := []string{
client.rosetta_mapping[0].ComponentID,
client.rosetta_mapping[len(client.rosetta_mapping)-1].ComponentID,
}

memberships := client.ListMemberships()
require.Len(t, memberships, len(client.components))
for _, id := range representativeIDs {
expected, err := client.GroupMembership(id)
require.NoError(t, err)
actual := membershipByID(t, memberships, id)
assert.ElementsMatch(t, expected, actual.GroupLabels)
assert.Empty(t, actual.PartitionName)
}

ungroupedID := representativeIDs[0]
for group, componentIDs := range client.groups {
filtered := make([]string, 0, len(componentIDs))
for _, id := range componentIDs {
if id != ungroupedID {
filtered = append(filtered, id)
}
}
client.groups[group] = filtered
}
ungrouped := membershipByID(t, client.ListMemberships(), ungroupedID)
assert.Empty(t, ungrouped.GroupLabels)
assert.NotNil(t, ungrouped.GroupLabels)

require.NoError(t, client.AddNodeToGroups(ungroupedID, []string{"new-group"}))
updated := membershipByID(t, client.ListMemberships(), ungroupedID)
assert.Equal(t, []string{"new-group"}, updated.GroupLabels)
}

func membershipByID(t *testing.T, memberships []sm.Membership, id string) sm.Membership {
t.Helper()
for _, membership := range memberships {
if membership.ID == id {
return membership
}
}
t.Fatalf("membership for %s not found", id)
return sm.Membership{}
}
21 changes: 13 additions & 8 deletions internal/smdclient/SMDclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,16 +283,21 @@ func (s *SMDClient) PopulateNodes() {
}
}

// Populate group membership for all nodes
log.Debug().Msg("Fetching group membership for all nodes")
memberships := make([]sm.Membership, 0)
if err := s.getSMD("/hsm/v2/memberships?type=node", &memberships); err != nil {
log.Error().Err(err).Msg("Failed to get SMD node memberships")
return
}

groupsByXname := make(map[string][]string, len(memberships))
for _, membership := range memberships {
groupsByXname[membership.ID] = membership.GroupLabels
}
for xname, node := range nextNodes {
ml := new(sm.Membership)
membershipEp := "/hsm/v2/memberships/" + xname
if err := s.getSMD(membershipEp, ml); err != nil {
log.Debug().Err(err).Msgf("Failed to get group membership for %s", xname)
node.Groups = []string{} // Empty groups if fetch fails
} else {
node.Groups = ml.GroupLabels
node.Groups = []string{}
if groups, found := groupsByXname[xname]; found && groups != nil {
node.Groups = groups
}
nextNodes[xname] = node
}
Expand Down
Loading
Loading