Skip to content

Commit 4010226

Browse files
feat(switch-controller): add ConfigureCertificate phase with RMS job polling
Extend the switch Configuring state machine with a certificate configuration sub-flow that runs after RotateOsPassword and before Validating. The handler submits an async RMS job via Component Manager and polls until completion. State machine (api-model): - Add ConfigureCertificateState { Start, WaitForComplete { job_id } } - Nest under ConfiguringState::ConfigureCertificate - RotateOsPassword now transitions into ConfigureCertificate(Start) Switch handler (configuring.rs): - Start: derive cert_name from switch.rack_id; build SwitchEndpoint from BMC MAC, NVOS interface, and vault credentials; call CM to start the job - WaitForComplete: poll CM for ConfigureSwitchCertificateState until Completed (→ Validating), Failed (→ Error), or in-progress (wait) - Skip certificate configuration when rack_id or component manager is absent Component Manager: - Expose configure_switch_certificate(endpoint, cert_name) → job_id - Expose get_configure_switch_certificate_job_status(job_id) → job status - Extend NvSwitchManager; implement in mock (configurable job status), NSM (unsupported), and RmsBackend (stub until librms RPCs land) - Add ConfigureSwitchCertificateState { Started, InProgress, Completed, Failed } Tests: - Integration tests for skip paths, Start → WaitForComplete, success/failure polling, and RotateOsPassword → ConfigureCertificate(Start) - Test fixtures for rack_id assignment and versioned state transitions Docs: - Add switch_configure_certificate.md with FSM detail and RMS sequence diagrams - Update switch.md transitions and link to the new design doc Signed-off-by: Vinod Chitrali <vchitrali@nvidia.com>
1 parent 791c8b5 commit 4010226

24 files changed

Lines changed: 1631 additions & 88 deletions

File tree

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ authors = ["NVIDIA Carbide Engineering <carbide-dev@exchange.nvidia.com>"]
2727
[workspace.dependencies]
2828
clap = { version = "4", features = ["derive", "env"] }
2929
libredfish = { git = "https://github.com/NVIDIA/libredfish.git", tag = "v0.44.11" }
30-
librms = { git = "https://github.com/NVIDIA/nv-rms-client.git", tag = "v0.9.0-rc1" }
30+
librms = { git = "https://github.com/NVIDIA/nv-rms-client.git", tag = "v0.9.0-mts-rc03" }
3131
ansi-to-html = "0.2.2"
3232

3333
tokio = { version = "1", features = ["full", "tracing"] }

crates/api-core/src/tests/switch_state_controller/fixtures/switch.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
* limitations under the License.
1616
*/
1717

18+
use carbide_uuid::rack::RackId;
1819
use carbide_uuid::switch::SwitchId;
19-
use model::switch::SwitchControllerState;
20+
use db::switch as db_switch;
21+
use model::switch::{ConfigureCertificateState, ConfiguringState, SwitchControllerState};
2022
use sqlx::PgConnection;
2123

2224
/// Helper function to set switch controller state directly in database
@@ -34,6 +36,56 @@ pub async fn set_switch_controller_state(
3436
Ok(())
3537
}
3638

39+
pub async fn set_switch_rack_id(
40+
txn: &mut PgConnection,
41+
switch_id: &SwitchId,
42+
rack_id: &RackId,
43+
) -> Result<(), sqlx::Error> {
44+
sqlx::query("UPDATE switches SET rack_id = $1 WHERE id = $2")
45+
.bind(rack_id)
46+
.bind(switch_id)
47+
.execute(txn)
48+
.await?;
49+
Ok(())
50+
}
51+
52+
pub async fn transition_switch_controller_state(
53+
txn: &mut PgConnection,
54+
switch_id: &SwitchId,
55+
new_state: SwitchControllerState,
56+
) -> Result<(), Box<dyn std::error::Error>> {
57+
let switch = db_switch::find_by_id(txn, switch_id)
58+
.await?
59+
.expect("switch should exist");
60+
db_switch::try_update_controller_state(
61+
txn,
62+
*switch_id,
63+
switch.controller_state.version,
64+
switch.controller_state.version.increment(),
65+
&new_state,
66+
)
67+
.await?;
68+
Ok(())
69+
}
70+
71+
pub fn configure_certificate_start_state() -> SwitchControllerState {
72+
SwitchControllerState::Configuring {
73+
config_state: ConfiguringState::ConfigureCertificate {
74+
configure_certificate: ConfigureCertificateState::Start,
75+
},
76+
}
77+
}
78+
79+
pub fn configure_certificate_wait_state(job_id: &str) -> SwitchControllerState {
80+
SwitchControllerState::Configuring {
81+
config_state: ConfiguringState::ConfigureCertificate {
82+
configure_certificate: ConfigureCertificateState::WaitForComplete {
83+
job_id: job_id.to_string(),
84+
},
85+
},
86+
}
87+
}
88+
3789
/// Helper function to mark switch as deleted
3890
pub async fn mark_switch_as_deleted(
3991
txn: &mut PgConnection,

0 commit comments

Comments
 (0)