Skip to content

Commit db45ca6

Browse files
authored
Merge pull request #104 from OpenCHAMI/power-control-output
Add Output Needed for Power Control
2 parents c9d5825 + e170787 commit db45ca6

1 file changed

Lines changed: 135 additions & 13 deletions

File tree

pkg/crawler/main.go

Lines changed: 135 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
6274
type 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) {
231264
func 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+
372494
func 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

Comments
 (0)