Skip to content

feat(bmc): propagate discovered IPMI port - #3687

Merged
poroh merged 1 commit into
NVIDIA:mainfrom
poroh:ipmi-port-plumbing
Jul 17, 2026
Merged

feat(bmc): propagate discovered IPMI port#3687
poroh merged 1 commit into
NVIDIA:mainfrom
poroh:ipmi-port-plumbing

Conversation

@poroh

@poroh poroh commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Redfish exposes the configured IPMI endpoint through ManagerNetworkProtocol. NICo previously discarded this information, causing consumers such as ssh-console to always fall back to the conventional IPMI port 623.

This change discovers the enabled IPMI port from ManagerNetworkProtocol, stores it in the exploration report, and returns it through the existing BMC metadata API. Consumers can now use the port reported by the BMC while retaining 623 as a fallback when no port is available.

As a secondary benefit, this enables end-to-end IPMI SOL testing with machine-a-tron and bmc-mock, where IPMI simulators use dynamically allocated ports.

Related issues

#3378

Type of Change

  • Add - New feature or capability
  • Change - Changes in existing functionality
  • Fix - Bug fixes
  • Remove - Removed features or deprecated functionality
  • Internal - Internal changes (refactoring, tests, docs, etc.)

Breaking Changes

  • This PR contains breaking changes

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • No testing required (docs, internal refactor, etc.)

Additional Notes

  • Missing or disabled IPMI configuration remains None, allowing consumers to retain their existing fallback behavior.
  • Invalid Redfish or stored port values are ignored safely.
  • The exploration report change is backward compatible because IpmiPort is optional.
  • ssh-console already consumes ipmi_port from the BMC metadata response, so no console-side changes are required.
  • Current exploration stores one Redfish manager. Multi-manager discovery and manager-to-system association are outside this change.

@poroh
poroh requested a review from a team as a code owner July 17, 2026 19:49
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4edc307c-5318-4dcb-bf92-2b560fea888c

📥 Commits

Reviewing files that changed from the base of the PR and between 89c84ec and 9df1010.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • Cargo.toml
  • crates/api-core/src/handlers/bmc_metadata.rs
  • crates/api-core/tests/integration/machine_bmc_metadata.rs
  • crates/api-db/src/explored_endpoints.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/api-model/src/test_support/dpu.rs
  • crates/api-model/src/test_support/managed_host.rs
  • crates/bmc-explorer/Cargo.toml
  • crates/bmc-explorer/src/manager.rs
  • crates/bmc-explorer/tests/integration/supermicro_gb300_explore.rs
  • crates/site-explorer/src/lib.rs
  • crates/site-explorer/src/redfish.rs
🚧 Files skipped from review as they are similar to previous changes (11)
  • crates/api-db/src/explored_endpoints.rs
  • crates/api-model/src/test_support/managed_host.rs
  • crates/api-core/src/handlers/bmc_metadata.rs
  • crates/api-model/src/test_support/dpu.rs
  • Cargo.toml
  • crates/bmc-explorer/tests/integration/supermicro_gb300_explore.rs
  • crates/site-explorer/src/lib.rs
  • crates/site-explorer/src/redfish.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/api-core/tests/integration/machine_bmc_metadata.rs
  • crates/bmc-explorer/src/manager.rs

Summary by CodeRabbit

  • New Features

    • BMC metadata now includes the configured IPMI port when available.
    • IPMI ports are discovered from Redfish manager network-protocol data.
    • Invalid, missing, or disabled IPMI port values are safely ignored.
  • Bug Fixes

    • BMC vendor information and IPMI port details are now retrieved together for more consistent metadata responses.
  • Tests

    • Added coverage for valid, missing, disabled, and invalid IPMI port configurations.

Walkthrough

The change adds optional IPMI port extraction to BMC exploration, carries it through manager reports and database lookup, and returns it from the BMC metadata API with handling for missing and invalid values.

Changes

IPMI metadata propagation

Layer / File(s) Summary
Explore and model IPMI ports
Cargo.toml, crates/bmc-explorer/..., crates/api-model/..., crates/site-explorer/...
The Redfish manager model and exploration flow extract, validate, and serialize optional IPMI ports.
Persist and return BMC metadata
crates/api-db/src/explored_endpoints.rs, crates/api-core/src/handlers/bmc_metadata.rs
The database lookup returns vendor and parsed IPMI port values, which the API maps into its response.
Validate IPMI metadata behavior
crates/bmc-explorer/tests/..., crates/api-core/tests/...
Tests cover valid, absent, disabled, null, and invalid IPMI port values.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BmcExplorer
  participant RedfishManager
  participant ExplorationReport
  participant MetadataApi
  participant Database
  BmcExplorer->>RedfishManager: Read network protocol data
  RedfishManager-->>BmcExplorer: Return IPMI enabled state and port
  BmcExplorer->>ExplorationReport: Store validated ipmi_port
  MetadataApi->>Database: Look up metadata by endpoint IP
  Database-->>MetadataApi: Return vendor and parsed ipmi_port
  MetadataApi-->>MetadataApi: Build BMC metadata response
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: discovering and propagating the IPMI port in BMC metadata.
Description check ✅ Passed The description is directly aligned with the changeset and clearly explains the new IPMI port discovery and propagation flow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/bmc-explorer/src/manager.rs (1)

262-295: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the repository table-test helper.

This validator’s input matrix should use check_cases or scenarios! instead of a hand-rolled case loop.

As per coding guidelines, “use table-driven tests using carbide-test-support scenarios (scenarios! / value_scenarios!) or explicit cases (check_cases / check_values) for parsers, validators, conversions, and similar input-variant coverage.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/bmc-explorer/src/manager.rs` around lines 262 - 295, The test extracts
its own table-test loop instead of using the repository helper. Update
tests::extracts_only_enabled_valid_ipmi_ports to express the existing input
matrix with carbide-test-support’s check_cases or scenarios! helper, preserving
all case names, inputs, and expected results.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/api-core/tests/integration/machine_bmc_metadata.rs`:
- Around line 177-205: Extend the invalid_port table in the BMC metadata test to
include the JSON value "null". Keep the existing database update, API request,
and assertions unchanged so the lookup path verifies that an explicitly null
IpmiPort returns None.

In `@crates/bmc-explorer/src/manager.rs`:
- Around line 36-44: Update enabled_ipmi_port in
crates/bmc-explorer/src/manager.rs to return None when an enabled reported port
is zero, while preserving validation for other values, and add a matching test
case. In crates/api-db/src/explored_endpoints.rs at the specified site, filter
parsed zero ports before exposing them to API clients.

---

Nitpick comments:
In `@crates/bmc-explorer/src/manager.rs`:
- Around line 262-295: The test extracts its own table-test loop instead of
using the repository helper. Update
tests::extracts_only_enabled_valid_ipmi_ports to express the existing input
matrix with carbide-test-support’s check_cases or scenarios! helper, preserving
all case names, inputs, and expected results.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 7eebc63a-2f98-4f32-bfab-45af1f73004c

📥 Commits

Reviewing files that changed from the base of the PR and between 0dae3ca and 89c84ec.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • Cargo.toml
  • crates/api-core/src/handlers/bmc_metadata.rs
  • crates/api-core/tests/integration/machine_bmc_metadata.rs
  • crates/api-db/src/explored_endpoints.rs
  • crates/api-model/src/site_explorer/mod.rs
  • crates/api-model/src/test_support/dpu.rs
  • crates/api-model/src/test_support/managed_host.rs
  • crates/bmc-explorer/Cargo.toml
  • crates/bmc-explorer/src/manager.rs
  • crates/bmc-explorer/tests/integration/supermicro_gb300_explore.rs
  • crates/site-explorer/src/lib.rs
  • crates/site-explorer/src/redfish.rs

Comment on lines +177 to +205
for invalid_port in [r#""not-a-port""#, "65536", "2147483648"] {
let mut txn = env.db_txn().await;
sqlx::query(
"UPDATE explored_endpoints SET exploration_report = \
jsonb_set(exploration_report, '{Managers,0,IpmiPort}', $2::jsonb, true) \
WHERE address = $1",
)
.bind(host_bmc_ip)
.bind(invalid_port)
.execute(txn.as_mut())
.await
.unwrap();
txn.commit().await.unwrap();

let metadata = env
.api()
.get_bmc_meta_data(tonic::Request::new(rpc::forge::BmcMetaDataGetRequest {
machine_id: host_machine.id.clone(),
request_type: rpc::forge::BmcRequestType::Ipmi.into(),
role: rpc::forge::UserRoles::Administrator.into(),
bmc_endpoint_request: None,
}))
.await
.unwrap()
.into_inner();

assert_eq!(metadata.ipmi_port, None, "stored port: {invalid_port}");
assert!(metadata.vendor.is_some_and(|vendor| !vendor.is_empty()));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Cover an explicitly stored JSON null.

The default assertion covers an omitted IpmiPort; these cases cover malformed/out-of-range values, but not IpmiPort: null. Add "null" to this case table so the database lookup path is verified for the promised null-safe behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/api-core/tests/integration/machine_bmc_metadata.rs` around lines 177 -
205, Extend the invalid_port table in the BMC metadata test to include the JSON
value "null". Keep the existing database update, API request, and assertions
unchanged so the lookup path verifies that an explicitly null IpmiPort returns
None.

Comment on lines +36 to +44
fn enabled_ipmi_port(
protocol_enabled: Option<Option<bool>>,
port: Option<Option<i64>>,
) -> Result<Option<u16>, TryFromIntError> {
if protocol_enabled != Some(Some(true)) {
return Ok(None);
}

port.flatten().map(u16::try_from).transpose()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject IPMI port zero throughout the metadata flow.

u16 conversion alone accepts zero, but zero is unusable and prevents consumers from applying their port-623 fallback.

  • crates/bmc-explorer/src/manager.rs#L36-L44: return None for an enabled reported port of zero and add a matching test case.
  • crates/api-db/src/explored_endpoints.rs#L349-L349: filter parsed zero values so malformed or historical JSON cannot reach API clients.
📍 Affects 2 files
  • crates/bmc-explorer/src/manager.rs#L36-L44 (this comment)
  • crates/api-db/src/explored_endpoints.rs#L349-L349
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/bmc-explorer/src/manager.rs` around lines 36 - 44, Update
enabled_ipmi_port in crates/bmc-explorer/src/manager.rs to return None when an
enabled reported port is zero, while preserving validation for other values, and
add a matching test case. In crates/api-db/src/explored_endpoints.rs at the
specified site, filter parsed zero ports before exposing them to API clients.

Signed-off-by: Dmitry Porokh <dporokh@nvidia.com>
@poroh
poroh force-pushed the ipmi-port-plumbing branch from 89c84ec to 9df1010 Compare July 17, 2026 20:09
@poroh
poroh merged commit 0e59cee into NVIDIA:main Jul 17, 2026
61 checks passed
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