@@ -59,6 +59,18 @@ type Manager struct {
5959 EthernetInterfaces []EthernetInterface `json:"ethernet_interfaces,omitempty"`
6060}
6161
62+ type Links struct {
63+ Chassis []string `json:"chassis,omitempty"`
64+ Managers []string `json:"managers,omitempty"`
65+ }
66+
67+ type Power struct {
68+ State string `json:"state,omitempty"`
69+ Mode string `json:"mode,omitempty"`
70+ RestorePolicy string `json:"restore_policy"`
71+ PowerControlIDs []string `json:"power_control_ids`
72+ }
73+
6274type InventoryDetail struct {
6375 URI string `json:"uri,omitempty"` // URI of the BMC
6476 UUID string `json:"uuid,omitempty"` // UUID of Node
@@ -70,7 +82,8 @@ type InventoryDetail struct {
7082 BiosVersion string `json:"bios_version,omitempty"` // Version of the BIOS
7183 EthernetInterfaces []EthernetInterface `json:"ethernet_interfaces,omitempty"` // Ethernet interfaces of the Node
7284 NetworkInterfaces []NetworkInterface `json:"network_interfaces,omitempty"` // Network interfaces of the Node
73- PowerState string `json:"power_state,omitempty"` // Power state of the Node
85+ Actions []string `json:"actions,omitempty"` // Available actions for Node
86+ Power Power `json:"power,omitempty"` // Power related settings of Node
7487 ProcessorCount int `json:"processor_count,omitempty"` // Processors of the Node
7588 ProcessorType string `json:"processor_type,omitempty"` // Processor type of the Node
7689 MemoryTotal float32 `json:"memory_total,omitempty"` // Total memory of the Node in Gigabytes
@@ -81,6 +94,7 @@ type InventoryDetail struct {
8194 Chassis_AssetTag string `json:"chassis_asset_tag,omitempty"` // Asset tag of the Chassis
8295 Chassis_Manufacturer string `json:"chassis_manufacturer,omitempty"` // Manufacturer of the Chassis
8396 Chassis_Model string `json:"chassis_model,omitempty"` // Model of the Chassis
97+ Links Links `json:"links,omitempty"` // Links to specific resources
8498}
8599
86100// CrawlBMCForSystems pulls all pertinent information from a BMC. It accepts a CrawlerConfig and returns a list of InventoryDetail structs.
@@ -131,9 +145,23 @@ func CrawlBMCForSystems(config CrawlerConfig) ([]InventoryDetail, error) {
131145 for _ , chassis := range rf_chassis {
132146 rf_chassis_systems , err := chassis .ComputerSystems ()
133147 if err == nil {
134- rf_systems = append (rf_systems , rf_chassis_systems ... )
148+ // rf_systems = append(rf_systems, rf_chassis_systems...)
135149 log .Debug ().Msgf ("found %d systems in chassis %s" , len (rf_chassis_systems ), chassis .ID )
136150 }
151+
152+ // Walk the systems found under Chassis with reference
153+ newSystems , err := walkSystems (rf_chassis_systems , chassis , config .URI )
154+ if err != nil {
155+ log .Error ().
156+ Err (err ).
157+ Str ("chassis_id" , chassis .ID ).
158+ Str ("uri" , config .URI ).
159+ Msg ("failed to get systems in chassis...continuing..." )
160+ continue
161+ }
162+
163+ // add systems found from chassis to total collection
164+ systems = append (systems , newSystems ... )
137165 }
138166 }
139167 rf_root_systems , err := rf_service .Systems ()
@@ -142,7 +170,12 @@ func CrawlBMCForSystems(config CrawlerConfig) ([]InventoryDetail, error) {
142170 }
143171 log .Debug ().Msgf ("found %d systems in ServiceRoot" , len (rf_root_systems ))
144172 rf_systems = append (rf_systems , rf_root_systems ... )
145- return walkSystems (rf_systems , nil , config .URI )
173+ newSystems , err := walkSystems (rf_systems , nil , config .URI )
174+ if err != nil {
175+ return systems , fmt .Errorf ("failed to get systems: %v" , err )
176+ }
177+ systems = append (systems , newSystems ... )
178+ return systems , nil
146179}
147180
148181// CrawlBMCForManagers connects to a BMC (Baseboard Management Controller) using the provided configuration,
@@ -231,16 +264,69 @@ func CrawlBMCForManagers(config CrawlerConfig) ([]Manager, error) {
231264func walkSystems (rf_systems []* redfish.ComputerSystem , rf_chassis * redfish.Chassis , baseURI string ) ([]InventoryDetail , error ) {
232265 systems := []InventoryDetail {}
233266 for _ , rf_computersystem := range rf_systems {
267+ var (
268+ managerLinks []string
269+ chassisLinks []string
270+ )
271+
272+ // get all of the links to managers
273+ rf_managers , err := rf_computersystem .ManagedBy ()
274+ if err != nil {
275+ log .Warn ().Err (err ).Msg ("failed to get system managers" )
276+ log .Error ().
277+ Err (err ).
278+ Str ("id" , rf_computersystem .ID ).
279+ Str ("system" , rf_computersystem .Name ).
280+ Msg ("failed to get manager for system" )
281+ } else {
282+ for _ , manager := range rf_managers {
283+ managerLinks = append (managerLinks , manager .ODataID )
284+ }
285+ }
286+
287+ if rf_chassis != nil {
288+ chassisLinks = append (chassisLinks , rf_chassis .ODataID )
289+ }
290+
291+ // convert supported reset types to []string
292+ actions := []string {}
293+ for _ , action := range rf_computersystem .SupportedResetTypes {
294+ actions = append (actions , string (action ))
295+ }
296+
297+ // get power-related details from rf_chassis
298+ power , err := rf_chassis .Power ()
299+ if err != nil {
300+ log .Warn ().Err (err ).Str ("id" , rf_computersystem .ID ).
301+ Str ("system" , rf_computersystem .Name ).Msg ("failed to get power-related details from chassis" )
302+ }
303+ // extract the power control odata.id resource
304+ powercontrolIDs := []string {}
305+ for _ , rf_powercontrol := range power .PowerControl {
306+ powercontrolIDs = append (powercontrolIDs , rf_powercontrol .ODataID )
307+ }
308+
309+ // get all of the links to the chassis
234310 system := InventoryDetail {
235- URI : baseURI + "/redfish/v1/Systems/" + rf_computersystem .ID ,
236- UUID : rf_computersystem .UUID ,
237- Name : rf_computersystem .Name ,
238- Manufacturer : rf_computersystem .Manufacturer ,
239- SystemType : string (rf_computersystem .SystemType ),
240- Model : rf_computersystem .Model ,
241- Serial : rf_computersystem .SerialNumber ,
242- BiosVersion : rf_computersystem .BIOSVersion ,
243- PowerState : string (rf_computersystem .PowerState ),
311+ URI : baseURI + "/redfish/v1/Systems/" + rf_computersystem .ID ,
312+ UUID : rf_computersystem .UUID ,
313+ Name : rf_computersystem .Name ,
314+ Manufacturer : rf_computersystem .Manufacturer ,
315+ SystemType : string (rf_computersystem .SystemType ),
316+ Model : rf_computersystem .Model ,
317+ Serial : rf_computersystem .SerialNumber ,
318+ BiosVersion : rf_computersystem .BIOSVersion ,
319+ Links : Links {
320+ Managers : managerLinks ,
321+ Chassis : chassisLinks ,
322+ },
323+ Power : Power {
324+ Mode : string (rf_computersystem .PowerMode ),
325+ State : string (rf_computersystem .PowerState ),
326+ RestorePolicy : string (rf_computersystem .PowerRestorePolicy ),
327+ PowerControlIDs : powercontrolIDs ,
328+ },
329+ Actions : actions ,
244330 ProcessorCount : rf_computersystem .ProcessorSummary .Count ,
245331 ProcessorType : rf_computersystem .ProcessorSummary .Model ,
246332 MemoryTotal : rf_computersystem .MemorySummary .TotalSystemMemoryGiB ,
@@ -257,7 +343,6 @@ func walkSystems(rf_systems []*redfish.ComputerSystem, rf_chassis *redfish.Chass
257343 if err != nil {
258344 log .Error ().Err (err ).Msg ("failed to get ethernet interfaces from computer system" )
259345 return systems , err
260-
261346 }
262347 for _ , rf_ethernetinterface := range rf_ethernetinterfaces {
263348 ethernetinterface := EthernetInterface {
@@ -369,6 +454,43 @@ func walkManagers(rf_managers []*redfish.Manager, baseURI string) ([]Manager, er
369454 return managers , nil
370455}
371456
457+ // func getPowerInfo(serviceroot *gofish.Service) ([]Power, error) {
458+ // // get the power control related information (Actions, URL, PowerControl, Links, etc.)
459+
460+ // // get the SupportedResetTypes from /redfish/v1/Systems
461+ // // get the Power/PowerControl from /redfish/v1/Chassis
462+ // rf_chassis, err := serviceroot.Chassis()
463+ // if err != nil {
464+
465+ // }
466+
467+ // power := []Power{}
468+ // for _, chassis := range rf_chassis {
469+ // rf_power, err := chassis.Power()
470+ // if err != nil {
471+
472+ // }
473+ // rf_computersystems, err := chassis.ComputerSystems()
474+ // if err != nil {
475+
476+ // }
477+
478+ // for _, computersystem := range rf_computersystems {
479+ // computersystem.SupportedResetTypes
480+ // }
481+
482+ // power = append(power, Power{
483+ // URL: "",
484+ // Control: PowerControl{
485+ // MemberID: "",
486+ // ResetTypes: rf_computersystem.SupportedResetTypes,
487+ // RelatedItems: []string{},
488+ // },
489+ // })
490+ // }
491+
492+ // }
493+
372494func loadBMCCreds (config CrawlerConfig ) (bmc.BMCCredentials , error ) {
373495 // NOTE: it is possible for the SecretStore to be nil, so we need a check
374496 if config .CredentialStore == nil {
0 commit comments