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
36 changes: 31 additions & 5 deletions cmd/discover-static.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"os"
"strings"

"github.com/spf13/cobra"

Expand Down Expand Up @@ -35,7 +36,9 @@ nodes:
xname: x1000c1s7b0n0
bmc_mac: de:ca:fc:0f:ee:ee
bmc_ip: 172.16.0.101
group: compute
groups:
- compute
- slurm
interfaces:
- mac_addr: de:ad:be:ee:ee:f1
ip_addrs:
Expand Down Expand Up @@ -327,17 +330,40 @@ See ochami-discover(1) for more details.`,
// Put together list of groups to add and which components to add to those groups
groupsToAdd := make(map[string]smd.Group)
for _, node := range nodes.Nodes {
// node.Group IS DEPRECATED IN FAVOR OF node.groups. This block should be
// deleted when node.Group is removed.
//
// For now, we merge node.Group with node.Groups. Since we use a dictionary for
// deduplication, this is trivial.
if node.Group != "" {
if len(strings.Trim(node.Name, " \t")) == 0 {
log.Logger.Warn().Msgf("node %s contains 'group', which is deprecated; use 'groups' instead", node.Xname)
} else {
log.Logger.Warn().Msgf("node %s (%s) contains 'group', which is deprecated; use 'groups' instead", node.Xname, node.Name)
}
if g, ok := groupsToAdd[node.Group]; !ok {
// Group doesn't exist yet, populate groupsToAdd with it
newGroup := smd.Group{
Label: node.Group,
Description: fmt.Sprintf("The %s group", node.Group),
}
newGroup.Members.IDs = []string{node.Xname}
groupsToAdd[node.Group] = newGroup
groupsToAdd[node.Group] = discover.AddMemberToGroup(newGroup, node.Xname)
} else {
// Update group membership with new node in groupsToAdd map
groupsToAdd[node.Group] = discover.AddMemberToGroup(g, node.Xname)
}
}
for _, group := range node.Groups {
if g, ok := groupsToAdd[group]; !ok {
// Group doesn't exist yet, populate groupsToAdd with it
newGroup := smd.Group{
Label: group,
Description: fmt.Sprintf("The %s group", group),
}
groupsToAdd[group] = discover.AddMemberToGroup(newGroup, node.Xname)
} else {
g.Members.IDs = append(g.Members.IDs, node.Xname)
groupsToAdd[node.Group] = g
// Update group membership with new node in groupsToAdd map
groupsToAdd[group] = discover.AddMemberToGroup(g, node.Xname)
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions man/ochami-discover.1.sc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ nodes:
xname: x1000c1s7b0n0
bmc_mac: de:ca:fc:0f:ee:ee
bmc_ip: 172.16.0.101
group: compute
groups:
- compute
interfaces:
- mac_addr: de:ad:be:ee:ee:f1
ip_addrs:
Expand Down Expand Up @@ -56,8 +57,10 @@ is used as the unique identifier for the node within the Component that gets
created for node.
- *bmc_mac* - MAC address of node's BMC.
- *bmc_ip* - Desired IP address of node's BMC.
- *group* - Optional group to add node to. This will get created during
discovery if it does not exist.
- *group* - *DEPRECATED.* Use *groups* instead. *group* will be removed in a
future release.
- *groups* - Optional list of groups to add node to. These will get created
during discovery if they do not exist.
- *interfaces* - A list of network interfaces for the node.
- *mac_addr* - MAC address of network interface.
- *ip_addrs* - List of IP addresses assigned to interface.
Expand Down
38 changes: 25 additions & 13 deletions pkg/discover/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ func (nl NodeList) String() string {
// Node represents a node entry in a payload file. Multiple of these are send to
// SMD to "discover" them.
type Node struct {
Name string `json:"name" yaml:"name"`
NID int64 `json:"nid" yaml:"nid"`
Xname string `json:"xname" yaml:"xname"`
Group string `json:"group" yaml:"group"`
BMCMac string `json:"bmc_mac" yaml:"bmc_mac"`
BMCIP string `json:"bmc_ip" yaml:"bmc_ip"`
Ifaces []Iface `json:"interfaces" yaml:"interfaces"`
Name string `json:"name" yaml:"name"`
NID int64 `json:"nid" yaml:"nid"`
Xname string `json:"xname" yaml:"xname"`
Group string `json:"group" yaml:"group"` // DEPRECATED
Groups []string `json:"groups" yaml:"groups"`
BMCMac string `json:"bmc_mac" yaml:"bmc_mac"`
BMCIP string `json:"bmc_ip" yaml:"bmc_ip"`
Ifaces []Iface `json:"interfaces" yaml:"interfaces"`
}

func (n Node) String() string {
Expand Down Expand Up @@ -112,8 +113,11 @@ func DiscoveryInfoV2(baseURI string, nl NodeList) (smd.ComponentSlice, smd.Redfi
return comps, rfes, ifaces, fmt.Errorf("invalid URI: %s", baseURI)
}

// Deduplication map for Components
compMap := make(map[string]string)
var (
compMap = make(map[string]string) // Deduplication map for SMD Components
systemMap = make(map[string]string) // Deduplication map for BMC Systems
managerMap = make(map[string]string) // Deduplication map for BMC Managers
)
for _, node := range nl.Nodes {
log.Logger.Debug().Msgf("generating component structure for node with xname %s", node.Xname)
if _, ok := compMap[node.Xname]; !ok {
Expand Down Expand Up @@ -149,10 +153,6 @@ func DiscoveryInfoV2(baseURI string, nl NodeList) (smd.ComponentSlice, smd.Redfi
rfe.IPAddress = node.BMCIP
rfe.SchemaVersion = 1 // Tells SMD to use new (v2) parsing code

// Deduplication maps for fake BMC Managers and Systems
systemMap := make(map[string]string)
managerMap := make(map[string]string)

// Create fake BMC "System" for node if it doesn't already exist
if _, ok := systemMap[node.Xname]; !ok {
log.Logger.Debug().Msgf("node %s: generating fake BMC System", node.Xname)
Expand Down Expand Up @@ -241,3 +241,15 @@ func DiscoveryInfoV2(baseURI string, nl NodeList) (smd.ComponentSlice, smd.Redfi
}
return comps, rfes, ifaces, nil
}

// AddMemberToGroup adds xname to group, ensuring deduplication.
func AddMemberToGroup(group smd.Group, xname string) smd.Group {
for _, x := range group.Members.IDs {
if x == xname {
return group
}
}
g := group
g.Members.IDs = append(g.Members.IDs, xname)
return g
}
50 changes: 50 additions & 0 deletions pkg/discover/discover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

"github.com/google/uuid"
"github.com/openchami/schemas/schemas"

"github.com/OpenCHAMI/ochami/pkg/client/smd"
)

func TestNodeList_String(t *testing.T) {
Expand Down Expand Up @@ -221,3 +223,51 @@ func TestDiscoveryInfoV2_Success(t *testing.T) {
}
}
}

func TestAddMemberToGroup(t *testing.T) {
newGroup := func(members []string) smd.Group {
var g smd.Group
g.Members.IDs = members
return g
}
tests := []struct {
name string
group smd.Group
xname string
expected smd.Group
}{
{
name: "add new member to empty group",
group: newGroup([]string{}),
xname: "x1000c0s0b0n0",
expected: newGroup([]string{"x1000c0s0b0n0"}),
},
{
name: "add new member to non-empty group",
group: newGroup([]string{"x1000c0s0b0n0", "x1000c0s0b1n0"}),
xname: "x1000c0s0b2n0",
expected: newGroup([]string{"x1000c0s0b0n0", "x1000c0s0b1n0", "x1000c0s0b2n0"}),
},
{
name: "member already exists in group",
group: newGroup([]string{"x1000c0s0b0n0", "x1000c0s0b1n0"}),
xname: "x1000c0s0b1n0",
expected: newGroup([]string{"x1000c0s0b0n0", "x1000c0s0b1n0"}),
},
{
name: "add member when group has one element",
group: newGroup([]string{"x1000c0s0b0n0"}),
xname: "x1000c0s0b1n0",
expected: newGroup([]string{"x1000c0s0b0n0", "x1000c0s0b1n0"}),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := AddMemberToGroup(tt.group, tt.xname)
if !reflect.DeepEqual(got, tt.expected) {
t.Errorf("AddMemberToGroup() = %+v, want %+v", got, tt.expected)
}
})
}
}
Loading