Skip to content

RFD 133: Evolve Magellan into the BMC interaction layer - #185

Closed
bmcdonald3 wants to merge 9 commits into
mainfrom
feature/RFD-133-test
Closed

RFD 133: Evolve Magellan into the BMC interaction layer#185
bmcdonald3 wants to merge 9 commits into
mainfrom
feature/RFD-133-test

Conversation

@bmcdonald3

@bmcdonald3 bmcdonald3 commented Aug 28, 2026

Copy link
Copy Markdown
Member

Taking over #133 from Alex.
See OpenCHAMI/roadmap#133 for discussion.

Draft until #180 is merged

Here is the original PR description:

This pull request introduces a new vendor-agnostic BMC (Baseboard Management Controller) client abstraction layer, enabling vendor-specific handling and plugin registration for BMC operations. It provides a unified interface for BMC interactions, a registry for vendor plugin detection and dispatch, and a manager for connection/session management. Comprehensive tests are included for all new components. The most important changes are as follows:

BMC Client Abstraction and Vendor Plugin System:

  • Introduced a new Client interface in pkg/bmc/client.go that abstracts BMC operations and shields callers from vendor-specific details. Added a default GenericClient implementation and a mechanism for vendor plugins to override behavior. Also defined the Vendor type and error handling for unsupported operations.
  • Added a plugin registry system in pkg/bmc/registry.go to allow vendor plugins to register detectors and factories. The clientFor function wraps a gofish client with the most specific registered vendor client or falls back to the generic client.
  • Registered the in-tree BMC vendor plugins in cmd/root.go by blank-importing pkg/bmc/vendors so their init() functions run and register themselves.
  • Added a Cray-specific vendor plugin in pkg/bmc/vendors/cray/cray.go that detects Cray BMCs and provides a placeholder for Cray-specific quirks.

Connection and Session Management:

  • Implemented a ConnConfig struct in pkg/bmc/conn.go for canonical BMC connection configuration, including credential resolution logic.
  • Added a Manager in pkg/bmc/manager.go as the single authority for opening and caching BMC sessions, performing vendor detection, and managing session lifecycles.

Testing and Validation:

  • Added comprehensive unit tests for the new client abstraction (pkg/bmc/client_test.go), connection configuration (pkg/bmc/conn_test.go), manager/session logic (pkg/bmc/manager_test.go), and plugin registry (pkg/bmc/registry_test.go). [1] [2] [3] [4]

For more info, see Contributing Guidelines.


Some testing to verify and convey functionality:

1. Automated baseline

make emulator

Second terminal:

go build -o magellan .
go test ./...
go test tests/api_test.go tests/compatibility_test.go

2. Test the enhanced power CLI directly

This uses the emulator without needing an inventory file:

./magellan power 127.0.0.1:5000 --insecure -u root -p root_password
$ ./magellan power 127.0.0.1:5000 --insecure -u root -p root_password
{"level":"info","time":"2026-08-28T11:55:10-07:00","caller":"/Users/benmcdonald/magellan/cmd/power.go:259","message":"connecting directly to BMC at 127.0.0.1:5000 (no inventory file required)"}
127.0.0.1:5000: On

3. Test the new REST service

Create a throwaway encrypted credential store and start the server:

export MASTER_KEY=$(./magellan secrets generatekey)

./magellan --file /tmp/magellan-emulator-secrets.json \
  secrets store https://127.0.0.1:5000 root:root_password

./magellan serve --host 127.0.0.1 --port 8443 --insecure \
  --auth-token test-token \
  --secrets-file /tmp/magellan-emulator-secrets.json

In another terminal:

curl http://127.0.0.1:8443/healthz

curl -H 'Authorization: Bearer test-token' \
  --get --data-urlencode 'bmc=https://127.0.0.1:5000' \
  --data-urlencode 'system=Node0' \
  http://127.0.0.1:8443/v1/power

curl -H 'Authorization: Bearer test-token' \
  -H 'Content-Type: application/json' \
  --data '{"bmc":"https://127.0.0.1:5000"}' \
  http://127.0.0.1:8443/v1/inventory
$ curl http://127.0.0.1:8443/healthz
{"status":"ok"}

$ curl -H 'Authorization: Bearer test-token' \
  --get --data-urlencode 'bmc=https://127.0.0.1:5000' \
  --data-urlencode 'system=Node0' \
  http://127.0.0.1:8443/v1/power
{"bmc":"https://127.0.0.1:5000","powerState":"On","system":"Node0"}

$ curl -H 'Authorization: Bearer test-token' \
  -H 'Content-Type: application/json' \
  --data '{"bmc":"https://127.0.0.1:5000"}' \
  http://127.0.0.1:8443/v1/inventory
{"bmc":"https://127.0.0.1:5000","managers":[{"uri":"https://127.0.0.1:5000/redfish/v1/Managers/MCU0","name":"MCU0","description":"Microcontroller Unit for Mezz0","type":"AuxiliaryController","serial_console":null,"command_shell":null},{"uri":"https://127.0.0.1:5000/redfish/v1/Managers/MCU1","name":"MCU1","description":"Microcontroller Unit for Mezz1","type":"AuxiliaryController","serial_console":null,"command_shell":null},{"uri":"https://127.0.0.1:5000/redfish/v1/Managers/BMC","name":"BMC","description":"Shasta Manager","type":"EnclosureManager","serial_console":null,"command_shell":null}],"systems":[{"uri":"https://127.0.0.1:5000/redfish/v1/Systems/Node0","manufacturer":"HPE","system_type":"Physical","name":"Node0","model":"HPE CRAY EX235a","serial":"SEH0221913701","serial_console":{"impi":{},"telnet":{},"ssh":{}},"bios_version":"ex235a.bios-1.3.6","ethernet_interfaces":[{"uri":"https://127.0.0.1:5000/redfish/v1/Systems/Node0/EthernetInterfaces/HPCNet1","mac":"Not Available","description":"SS11 200Gb 2P NIC Mezz REV02 (HSN)"},{"uri":"https://127.0.0.1:5000/redfish/v1/Systems/Node0/EthernetInterfaces/ManagementEthernet","mac":"02:0b:b8:00:30:00","description":"Node Maintenance Network"},{"uri":"https://127.0.0.1:5000/redfish/v1/Systems/Node0/EthernetInterfaces/HPCNet2","mac":"Not Available","description":"SS11 200Gb 2P NIC Mezz REV02 (HSN)"},{"uri":"https://127.0.0.1:5000/redfish/v1/Systems/Node0/EthernetInterfaces/HPCNet3","mac":"Not Available","description":"SS11 200Gb 2P NIC Mezz REV02 (HSN)"},{"uri":"https://127.0.0.1:5000/redfish/v1/Systems/Node0/EthernetInterfaces/HPCNet0","mac":"Not Available","description":"SS11 200Gb 2P NIC Mezz REV02 (HSN)"}],"actions":["On","ForceOff","Off"],"power":{"state":"On"},"processor_count":9,"processor_type":"AMD INSTINCT MI200 (MCM) OAM LC","memory_total":512,"links":{},"node_id":"Node0"}]}

alexlovelltroy and others added 8 commits August 28, 2026 11:40
Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>

Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>

Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
- Updated imports from redfish to schemas in various files to align with the new package structure.
- Modified Client interface methods to return types from schemas instead of redfish.
- Adjusted implementations in GenericClient to accommodate the new schemas types.
- Updated tests to reflect changes in the types used for power states and reset types.
- Refactored functions in collect, crawler, power, service, and update packages to utilize schemas types.
- Introduced helper functions to dereference optional numeric fields for better handling of nil values.

Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>

Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
…BMC layer

Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>

Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
- Add middleware for request logging and bearer token authentication in the server.
- Create response handling functions for JSON responses and error messages.
- Develop the main server structure to handle API routes for inventory and power operations.
- Implement health check endpoints for liveness and readiness.
- Introduce a mock Redfish service for testing power state transitions.
- Add power transition logic with confirmation and escalation handling.
- Create tests for various power operations, including success, timeout, and escalation scenarios.
- Enhance service layer to support power transition operations.

Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>

Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
* Refactor to upgrade to gofish 0.22.0 with new schemas package

- Updated imports from redfish to schemas in various files to align with the new package structure.
- Modified Client interface methods to return types from schemas instead of redfish.
- Adjusted implementations in GenericClient to accommodate the new schemas types.
- Updated tests to reflect changes in the types used for power states and reset types.
- Refactored functions in collect, crawler, power, service, and update packages to utilize schemas types.
- Introduced helper functions to dereference optional numeric fields for better handling of nil values.

Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>

* feat: implement context-aware power operations and reset handling in BMC layer

Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>

* feat: enhance power command to support flexible node identifiers and improve inventory handling

Signed-off-by: Alex Lovell-Troy <alovelltroy@lanl.gov>

---------

Signed-off-by: Alex Lovell-Troy <alex@lovelltroy.org>
Signed-off-by: Alex Lovell-Troy <alovelltroy@lanl.gov>

Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
@bmcdonald3
bmcdonald3 marked this pull request as draft August 28, 2026 19:25
Signed-off-by: Ben McDonald <ben.mcdonald@hpe.com>
@bmcdonald3 bmcdonald3 closed this Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants