From e982b4cb5798a335df650f8846e02c2036893312 Mon Sep 17 00:00:00 2001 From: Srikar Date: Thu, 27 Aug 2026 22:20:43 -0700 Subject: [PATCH] feat(admin-cli): add health-history commands for switch, power-shelf, rack, and machine --- crates/admin-cli/src/health_utils.rs | 79 +++++++++++++++++- .../admin-cli/src/machine/health_history.rs | 47 +++++++++++ crates/admin-cli/src/machine/mod.rs | 6 ++ crates/admin-cli/src/machine/tests.rs | 42 ++++++++++ .../src/power_shelf/health_history.rs | 47 +++++++++++ crates/admin-cli/src/power_shelf/mod.rs | 3 + crates/admin-cli/src/power_shelf/tests.rs | 23 ++++-- crates/admin-cli/src/rack/health_history.rs | 47 +++++++++++ crates/admin-cli/src/rack/mod.rs | 6 ++ crates/admin-cli/src/rack/tests.rs | 42 ++++++++++ crates/admin-cli/src/rpc.rs | 80 +++++++++++++++++++ crates/admin-cli/src/switch/health_history.rs | 47 +++++++++++ crates/admin-cli/src/switch/mod.rs | 6 ++ crates/admin-cli/src/switch/tests.rs | 42 ++++++++++ .../machine/machine-health-history.md | 51 ++++++++++++ .../commands/machine/machine.md | 1 + .../power-shelf/power-shelf-health-history.md | 52 ++++++++++++ .../commands/power-shelf/power-shelf.md | 1 + .../commands/rack/rack-health-history.md | 51 ++++++++++++ .../nico-admin-cli/commands/rack/rack.md | 1 + .../commands/switch/switch-health-history.md | 51 ++++++++++++ .../nico-admin-cli/commands/switch/switch.md | 1 + 22 files changed, 718 insertions(+), 8 deletions(-) create mode 100644 crates/admin-cli/src/machine/health_history.rs create mode 100644 crates/admin-cli/src/machine/tests.rs create mode 100644 crates/admin-cli/src/power_shelf/health_history.rs create mode 100644 crates/admin-cli/src/rack/health_history.rs create mode 100644 crates/admin-cli/src/rack/tests.rs create mode 100644 crates/admin-cli/src/switch/health_history.rs create mode 100644 crates/admin-cli/src/switch/tests.rs create mode 100644 docs/manuals/nico-admin-cli/commands/machine/machine-health-history.md create mode 100644 docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf-health-history.md create mode 100644 docs/manuals/nico-admin-cli/commands/rack/rack-health-history.md create mode 100644 docs/manuals/nico-admin-cli/commands/switch/switch-health-history.md diff --git a/crates/admin-cli/src/health_utils.rs b/crates/admin-cli/src/health_utils.rs index 2a3122715f..dd7f066c33 100644 --- a/crates/admin-cli/src/health_utils.rs +++ b/crates/admin-cli/src/health_utils.rs @@ -17,7 +17,8 @@ use ::rpc::admin_cli::OutputFormat; use ::rpc::forge::{self as forgerpc}; -use prettytable::{Table, row}; +use prettytable::{Cell, Row, Table, row}; +use serde::Serialize; use crate::errors::{CarbideCliError, CarbideCliResult}; use crate::machine::{HealthReportTemplates, get_empty_template, get_health_report}; @@ -67,6 +68,82 @@ pub(crate) fn display_health_reports( Ok(()) } +/// One row of an object's health history, summarized for tabular display. +#[derive(Serialize)] +struct HealthHistoryRecordView { + time: String, + source: String, + status: String, + alerts: Vec, +} + +impl From<&forgerpc::HealthHistoryRecord> for HealthHistoryRecordView { + fn from(record: &forgerpc::HealthHistoryRecord) -> Self { + let health = record.health.as_ref(); + let source = health.map(|h| h.source.clone()).unwrap_or_default(); + let alerts: Vec = health + .map(|h| h.alerts.iter().map(|alert| alert.id.clone()).collect()) + .unwrap_or_default(); + let status = if alerts.is_empty() { + "Healthy" + } else { + "Alerting" + } + .to_string(); + Self { + time: record.time.map(|time| time.to_string()).unwrap_or_default(), + source, + status, + alerts, + } + } +} + +fn health_history_table(records: &[HealthHistoryRecordView]) -> Table { + let mut table = Table::new(); + table.set_titles(Row::new( + ["Time", "Source", "Status", "Alerts"] + .into_iter() + .map(Cell::new) + .collect(), + )); + for record in records { + let alerts = if record.alerts.is_empty() { + "-".to_string() + } else { + record.alerts.join(", ") + }; + table.add_row(row![record.time, record.source, record.status, alerts]); + } + table +} + +/// Display an object's health history in the requested output format. Shared by +/// the per-resource `health-history` subcommands, whose only difference is the +/// RPC that produced `history`. +pub(crate) fn display_health_history( + object_id: &str, + history: Vec, + output_format: OutputFormat, +) -> CarbideCliResult<()> { + if history.is_empty() { + println!("No health history found for {object_id}"); + return Ok(()); + } + + let records: Vec = + history.iter().map(HealthHistoryRecordView::from).collect(); + match output_format { + OutputFormat::Json => println!("{}", serde_json::to_string_pretty(&records)?), + OutputFormat::Yaml => println!("{}", serde_yaml::to_string(&records)?), + OutputFormat::Csv => { + health_history_table(&records).to_csv(std::io::stdout())?; + } + OutputFormat::AsciiTable => health_history_table(&records).printstd(), + } + Ok(()) +} + /// Resolve a health report from either a template or raw JSON. pub(crate) fn resolve_health_report( template: Option, diff --git a/crates/admin-cli/src/machine/health_history.rs b/crates/admin-cli/src/machine/health_history.rs new file mode 100644 index 0000000000..f749394f48 --- /dev/null +++ b/crates/admin-cli/src/machine/health_history.rs @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use carbide_uuid::machine::MachineId; +use clap::Parser; + +use crate::cfg::run::Run; +use crate::cfg::runtime::RuntimeContext; +use crate::errors::CarbideCliResult; +use crate::health_utils::display_health_history; + +#[derive(Parser, Debug)] +#[command(after_long_help = "\ +EXAMPLES: + +Show health history for a machine: + $ nico-admin-cli machine health-history fm100ht038bg3qsho433vkg684heguv282qaggmrsh2ugn1qk096n2c6hcg + +")] +pub(crate) struct Args { + #[clap(help = "Machine ID to show health history for")] + machine_id: MachineId, +} + +impl Run for Args { + async fn run(self, ctx: &mut RuntimeContext) -> CarbideCliResult<()> { + let history = ctx + .api_client + .get_machine_health_history(self.machine_id) + .await?; + display_health_history(&self.machine_id.to_string(), history, ctx.config.format) + } +} diff --git a/crates/admin-cli/src/machine/mod.rs b/crates/admin-cli/src/machine/mod.rs index 493f23eee3..7b5289691d 100644 --- a/crates/admin-cli/src/machine/mod.rs +++ b/crates/admin-cli/src/machine/mod.rs @@ -19,6 +19,7 @@ mod auto_update; mod common; mod force_delete; mod hardware_info; +mod health_history; mod health_report; mod metadata; pub(crate) mod network; @@ -27,6 +28,9 @@ mod positions; mod reboot; mod show; +#[cfg(test)] +mod tests; + // Cross-module re-exports. pub(crate) use auto_update::args::Args as MachineAutoupdate; use clap::Parser; @@ -83,4 +87,6 @@ pub(crate) enum Cmd { Positions(positions::Args), #[clap(subcommand, about = "Update/show NVLink info for an MNNVL machine")] NvlinkInfo(nvlink_info::Args), + #[clap(about = "Show machine health history")] + HealthHistory(health_history::Args), } diff --git a/crates/admin-cli/src/machine/tests.rs b/crates/admin-cli/src/machine/tests.rs new file mode 100644 index 0000000000..9997a098d1 --- /dev/null +++ b/crates/admin-cli/src/machine/tests.rs @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use carbide_uuid::machine::MachineId; +use clap::CommandFactory; + +use super::*; +use crate::test_support::parse_leaf; + +const SAMPLE_MACHINE_ID: &str = "fm100ht038bg3qsho433vkg684heguv282qaggmrsh2ugn1qk096n2c6hcg"; + +#[test] +fn verify_cmd_structure() { + Cmd::command().debug_assert(); +} + +#[test] +fn parse_health_history_command() { + let matches = parse_leaf::( + &["machine", "health-history", SAMPLE_MACHINE_ID], + &["health-history"], + ) + .expect("health-history should parse"); + let machine_id = matches + .get_one::("machine_id") + .expect("machine ID is required"); + assert_eq!(machine_id, &SAMPLE_MACHINE_ID.parse::().unwrap()); +} diff --git a/crates/admin-cli/src/power_shelf/health_history.rs b/crates/admin-cli/src/power_shelf/health_history.rs new file mode 100644 index 0000000000..b2180a63ca --- /dev/null +++ b/crates/admin-cli/src/power_shelf/health_history.rs @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use carbide_uuid::power_shelf::PowerShelfId; +use clap::Parser; + +use crate::cfg::run::Run; +use crate::cfg::runtime::RuntimeContext; +use crate::errors::CarbideCliResult; +use crate::health_utils::display_health_history; + +#[derive(Parser, Debug)] +#[command(after_long_help = "\ +EXAMPLES: + +Show health history for a power shelf: + $ nico-admin-cli power-shelf health-history ps100ht038bg3qsho433vkg684heguv282qaggmrsh2ugn1qk096n2c6hcg + +")] +pub(crate) struct Args { + #[clap(help = "Power shelf ID to show health history for")] + power_shelf_id: PowerShelfId, +} + +impl Run for Args { + async fn run(self, ctx: &mut RuntimeContext) -> CarbideCliResult<()> { + let history = ctx + .api_client + .get_power_shelf_health_history(self.power_shelf_id) + .await?; + display_health_history(&self.power_shelf_id.to_string(), history, ctx.config.format) + } +} diff --git a/crates/admin-cli/src/power_shelf/mod.rs b/crates/admin-cli/src/power_shelf/mod.rs index 2e3617c843..aeaa5b6590 100644 --- a/crates/admin-cli/src/power_shelf/mod.rs +++ b/crates/admin-cli/src/power_shelf/mod.rs @@ -18,6 +18,7 @@ mod decommission; mod delete; mod force_delete; +mod health_history; mod health_report; mod list; mod maintenance; @@ -58,4 +59,6 @@ pub(crate) enum Cmd { visible_alias = "hr" )] HealthReport(health_report::Args), + #[clap(about = "Show power shelf health history")] + HealthHistory(health_history::Args), } diff --git a/crates/admin-cli/src/power_shelf/tests.rs b/crates/admin-cli/src/power_shelf/tests.rs index c4b9e988e9..8c2ef1aef6 100644 --- a/crates/admin-cli/src/power_shelf/tests.rs +++ b/crates/admin-cli/src/power_shelf/tests.rs @@ -31,15 +31,8 @@ use clap::CommandFactory; use super::*; use crate::test_support::parse_leaf; -/// Sample power-shelf id used in CLI parse tests. Must round-trip through -/// `PowerShelfId::from_str`, which `clap` uses to coerce identifier arguments. const SAMPLE_PS_ID_1: &str = "ps100htjtiaehv1n5vh67tbmqq4eabcjdng40f7jupsadbedhruh6rag1l0"; -// verify_cmd_structure runs a baseline clap debug_assert() -// to do basic command configuration checking and validation, -// ensuring things like unique argument definitions, group -// configurations, argument references, etc. Things that would -// otherwise be missed until runtime. #[test] fn verify_cmd_structure() { Cmd::command().debug_assert(); @@ -63,6 +56,22 @@ fn parse_decommission_lifecycle_commands() { ); } +#[test] +fn parse_health_history_command() { + let matches = parse_leaf::( + &["power-shelf", "health-history", SAMPLE_PS_ID_1], + &["health-history"], + ) + .expect("health-history should parse"); + let power_shelf_id = matches + .get_one::("power_shelf_id") + .expect("power shelf ID is required"); + assert_eq!( + power_shelf_id, + &SAMPLE_PS_ID_1.parse::().unwrap() + ); +} + #[test] fn parse_force_delete_cleanup_flags() { scenarios!( diff --git a/crates/admin-cli/src/rack/health_history.rs b/crates/admin-cli/src/rack/health_history.rs new file mode 100644 index 0000000000..156ab3676a --- /dev/null +++ b/crates/admin-cli/src/rack/health_history.rs @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use carbide_uuid::rack::RackId; +use clap::Parser; + +use crate::cfg::run::Run; +use crate::cfg::runtime::RuntimeContext; +use crate::errors::CarbideCliResult; +use crate::health_utils::display_health_history; + +#[derive(Parser, Debug)] +#[command(after_long_help = "\ +EXAMPLES: + +Show health history for a rack: + $ nico-admin-cli rack health-history ipp6-b03-gb-nvl-124-mini2 + +")] +pub(crate) struct Args { + #[clap(help = "Rack ID to show health history for")] + rack_id: RackId, +} + +impl Run for Args { + async fn run(self, ctx: &mut RuntimeContext) -> CarbideCliResult<()> { + let history = ctx + .api_client + .get_rack_health_history(self.rack_id.clone()) + .await?; + display_health_history(self.rack_id.as_ref(), history, ctx.config.format) + } +} diff --git a/crates/admin-cli/src/rack/mod.rs b/crates/admin-cli/src/rack/mod.rs index fa23ddd07d..4a0b5fd695 100644 --- a/crates/admin-cli/src/rack/mod.rs +++ b/crates/admin-cli/src/rack/mod.rs @@ -17,6 +17,7 @@ mod delete; mod force_delete; +mod health_history; mod list; mod maintenance; mod metadata; @@ -24,6 +25,9 @@ mod profile; mod show; mod state_history; +#[cfg(test)] +mod tests; + use clap::Parser; use crate::cfg::dispatch::Dispatch; @@ -46,4 +50,6 @@ pub(crate) enum Cmd { Maintenance(maintenance::Args), #[clap(about = "Show rack state history")] StateHistory(state_history::Args), + #[clap(about = "Show rack health history")] + HealthHistory(health_history::Args), } diff --git a/crates/admin-cli/src/rack/tests.rs b/crates/admin-cli/src/rack/tests.rs new file mode 100644 index 0000000000..747c2513f5 --- /dev/null +++ b/crates/admin-cli/src/rack/tests.rs @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use carbide_uuid::rack::RackId; +use clap::CommandFactory; + +use super::*; +use crate::test_support::parse_leaf; + +const SAMPLE_RACK_ID: &str = "ipp6-b03-gb-nvl-124-mini2"; + +#[test] +fn verify_cmd_structure() { + Cmd::command().debug_assert(); +} + +#[test] +fn parse_health_history_command() { + let matches = parse_leaf::( + &["rack", "health-history", SAMPLE_RACK_ID], + &["health-history"], + ) + .expect("health-history should parse"); + let rack_id = matches + .get_one::("rack_id") + .expect("rack ID is required"); + assert_eq!(rack_id, &SAMPLE_RACK_ID.parse::().unwrap()); +} diff --git a/crates/admin-cli/src/rpc.rs b/crates/admin-cli/src/rpc.rs index fe3b9e6716..08cd6f4725 100644 --- a/crates/admin-cli/src/rpc.rs +++ b/crates/admin-cli/src/rpc.rs @@ -638,6 +638,86 @@ impl ApiClient { .unwrap_or_default()) } + pub(crate) async fn get_switch_health_history( + &self, + switch_id: SwitchId, + ) -> CarbideCliResult> { + let mut result = self + .0 + .find_switch_health_histories(rpc::SwitchHealthHistoriesRequest { + switch_ids: vec![switch_id], + start_time: None, + end_time: None, + }) + .await?; + + Ok(result + .histories + .remove(&switch_id.to_string()) + .map(|h| h.records) + .unwrap_or_default()) + } + + pub(crate) async fn get_power_shelf_health_history( + &self, + power_shelf_id: PowerShelfId, + ) -> CarbideCliResult> { + let mut result = self + .0 + .find_power_shelf_health_histories(rpc::PowerShelfHealthHistoriesRequest { + power_shelf_ids: vec![power_shelf_id], + start_time: None, + end_time: None, + }) + .await?; + + Ok(result + .histories + .remove(&power_shelf_id.to_string()) + .map(|h| h.records) + .unwrap_or_default()) + } + + pub(crate) async fn get_rack_health_history( + &self, + rack_id: RackId, + ) -> CarbideCliResult> { + let mut result = self + .0 + .find_rack_health_histories(rpc::RackHealthHistoriesRequest { + rack_ids: vec![rack_id.clone()], + start_time: None, + end_time: None, + }) + .await?; + + Ok(result + .histories + .remove(&rack_id.to_string()) + .map(|h| h.records) + .unwrap_or_default()) + } + + pub(crate) async fn get_machine_health_history( + &self, + machine_id: MachineId, + ) -> CarbideCliResult> { + let mut result = self + .0 + .find_machine_health_histories(rpc::MachineHealthHistoriesRequest { + machine_ids: vec![machine_id], + start_time: None, + end_time: None, + }) + .await?; + + Ok(result + .histories + .remove(&machine_id.to_string()) + .map(|h| h.records) + .unwrap_or_default()) + } + pub(crate) async fn get_segment_state_history( &self, segment_id: NetworkSegmentId, diff --git a/crates/admin-cli/src/switch/health_history.rs b/crates/admin-cli/src/switch/health_history.rs new file mode 100644 index 0000000000..61aa4b408b --- /dev/null +++ b/crates/admin-cli/src/switch/health_history.rs @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use carbide_uuid::switch::SwitchId; +use clap::Parser; + +use crate::cfg::run::Run; +use crate::cfg::runtime::RuntimeContext; +use crate::errors::CarbideCliResult; +use crate::health_utils::display_health_history; + +#[derive(Parser, Debug)] +#[command(after_long_help = "\ +EXAMPLES: + +Show health history for a switch: + $ nico-admin-cli switch health-history sw100nt038bg3qsho433vkg684heguv282qaggmrsh2ugn1qk096n2c6hcg + +")] +pub(crate) struct Args { + #[clap(help = "Switch ID to show health history for")] + switch_id: SwitchId, +} + +impl Run for Args { + async fn run(self, ctx: &mut RuntimeContext) -> CarbideCliResult<()> { + let history = ctx + .api_client + .get_switch_health_history(self.switch_id) + .await?; + display_health_history(&self.switch_id.to_string(), history, ctx.config.format) + } +} diff --git a/crates/admin-cli/src/switch/mod.rs b/crates/admin-cli/src/switch/mod.rs index d8cca6ef76..604ab92bf8 100644 --- a/crates/admin-cli/src/switch/mod.rs +++ b/crates/admin-cli/src/switch/mod.rs @@ -16,11 +16,15 @@ */ mod force_delete; +mod health_history; mod health_report; mod list; mod metadata; mod show; +#[cfg(test)] +mod tests; + use clap::Parser; use crate::cfg::dispatch::Dispatch; @@ -42,4 +46,6 @@ pub(crate) enum Cmd { visible_alias = "hr" )] HealthReport(health_report::Args), + #[clap(about = "Show switch health history")] + HealthHistory(health_history::Args), } diff --git a/crates/admin-cli/src/switch/tests.rs b/crates/admin-cli/src/switch/tests.rs new file mode 100644 index 0000000000..eb67b93c89 --- /dev/null +++ b/crates/admin-cli/src/switch/tests.rs @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use carbide_uuid::switch::SwitchId; +use clap::CommandFactory; + +use super::*; +use crate::test_support::parse_leaf; + +const SAMPLE_SWITCH_ID: &str = "sw100nsmnq69j4ntqlj162fnnbvg747gfqbicaa6tqgq6spocirfle7rom0"; + +#[test] +fn verify_cmd_structure() { + Cmd::command().debug_assert(); +} + +#[test] +fn parse_health_history_command() { + let matches = parse_leaf::( + &["switch", "health-history", SAMPLE_SWITCH_ID], + &["health-history"], + ) + .expect("health-history should parse"); + let switch_id = matches + .get_one::("switch_id") + .expect("switch ID is required"); + assert_eq!(switch_id, &SAMPLE_SWITCH_ID.parse::().unwrap()); +} diff --git a/docs/manuals/nico-admin-cli/commands/machine/machine-health-history.md b/docs/manuals/nico-admin-cli/commands/machine/machine-health-history.md new file mode 100644 index 0000000000..c093c953ae --- /dev/null +++ b/docs/manuals/nico-admin-cli/commands/machine/machine-health-history.md @@ -0,0 +1,51 @@ +# `nico-admin-cli machine health-history` + +_[Hardware commands](../../hardware.md) › [machine](./machine.md) › **health-history**_ + +## NAME + +nico-admin-cli-machine-health-history - Show machine health history + +## SYNOPSIS + +**nico-admin-cli machine health-history** \[**--extended**\] +\[**--sort-by**\] \[**-h**\|**--help**\] \<*MACHINE_ID*\> + +## DESCRIPTION + +Show machine health history + +## OPTIONS + +**--extended** +Extended result output. + +This used by measured boot, where basic output contains just what you +probably care about, and "extended" output also dumps out all the +internal UUIDs that are used to associate instances. + +**--sort-by** *\* \[default: primary-id\] +Sort output by specified field\ + +\ +*Possible values:* + +- primary-id: Sort by the primary ID + +- state: Sort by state + +**-h**, **--help** +Print help (see a summary with -h) + +\<*MACHINE_ID*\> +Machine ID to show health history for + +## Examples + +```sh +nico-admin-cli machine health-history fm100ht038bg3qsho433vkg684heguv282qaggmrsh2ugn1qk096n2c6hcg +``` + +--- + +**See also:** [Hardware commands](../../hardware.md) · [CLI reference index](../../README.md) diff --git a/docs/manuals/nico-admin-cli/commands/machine/machine.md b/docs/manuals/nico-admin-cli/commands/machine/machine.md index 48a413b115..a42cd2f7b9 100644 --- a/docs/manuals/nico-admin-cli/commands/machine/machine.md +++ b/docs/manuals/nico-admin-cli/commands/machine/machine.md @@ -51,6 +51,7 @@ Print help (see a summary with -h) | [`hardware-info`](./machine-hardware-info.md) | Update/show machine hardware info | | [`positions`](./machine-positions.md) | Show physical location info for machines in rack-based systems | | [`nvlink-info`](./machine-nvlink-info.md) | Update/show NVLink info for an MNNVL machine | +| [`health-history`](./machine-health-history.md) | Show machine health history | --- diff --git a/docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf-health-history.md b/docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf-health-history.md new file mode 100644 index 0000000000..879ebc392c --- /dev/null +++ b/docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf-health-history.md @@ -0,0 +1,52 @@ +# `nico-admin-cli power-shelf health-history` + +_[Hardware commands](../../hardware.md) › [power-shelf](./power-shelf.md) › **health-history**_ + +## NAME + +nico-admin-cli-power-shelf-health-history - Show power shelf health +history + +## SYNOPSIS + +**nico-admin-cli power-shelf health-history** \[**--extended**\] +\[**--sort-by**\] \[**-h**\|**--help**\] \<*POWER_SHELF_ID*\> + +## DESCRIPTION + +Show power shelf health history + +## OPTIONS + +**--extended** +Extended result output. + +This used by measured boot, where basic output contains just what you +probably care about, and "extended" output also dumps out all the +internal UUIDs that are used to associate instances. + +**--sort-by** *\* \[default: primary-id\] +Sort output by specified field\ + +\ +*Possible values:* + +- primary-id: Sort by the primary ID + +- state: Sort by state + +**-h**, **--help** +Print help (see a summary with -h) + +\<*POWER_SHELF_ID*\> +Power shelf ID to show health history for + +## Examples + +```sh +nico-admin-cli power-shelf health-history ps100ht038bg3qsho433vkg684heguv282qaggmrsh2ugn1qk096n2c6hcg +``` + +--- + +**See also:** [Hardware commands](../../hardware.md) · [CLI reference index](../../README.md) diff --git a/docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf.md b/docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf.md index 81d4abd545..d58d2b39f0 100644 --- a/docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf.md +++ b/docs/manuals/nico-admin-cli/commands/power-shelf/power-shelf.md @@ -49,6 +49,7 @@ Print help (see a summary with -h) | [`metadata`](./power-shelf-metadata.md) | Manage Power Shelf Metadata | | [`maintenance`](./power-shelf-maintenance.md) | Request a power shelf maintenance operation (PowerOn / PowerOff) | | [`health-report`](./power-shelf-health-report.md) | Manage health report sources | +| [`health-history`](./power-shelf-health-history.md) | Show power shelf health history | --- diff --git a/docs/manuals/nico-admin-cli/commands/rack/rack-health-history.md b/docs/manuals/nico-admin-cli/commands/rack/rack-health-history.md new file mode 100644 index 0000000000..556f9a4ee5 --- /dev/null +++ b/docs/manuals/nico-admin-cli/commands/rack/rack-health-history.md @@ -0,0 +1,51 @@ +# `nico-admin-cli rack health-history` + +_[Hardware commands](../../hardware.md) › [rack](./rack.md) › **health-history**_ + +## NAME + +nico-admin-cli-rack-health-history - Show rack health history + +## SYNOPSIS + +**nico-admin-cli rack health-history** \[**--extended**\] +\[**--sort-by**\] \[**-h**\|**--help**\] \<*RACK_ID*\> + +## DESCRIPTION + +Show rack health history + +## OPTIONS + +**--extended** +Extended result output. + +This used by measured boot, where basic output contains just what you +probably care about, and "extended" output also dumps out all the +internal UUIDs that are used to associate instances. + +**--sort-by** *\* \[default: primary-id\] +Sort output by specified field\ + +\ +*Possible values:* + +- primary-id: Sort by the primary ID + +- state: Sort by state + +**-h**, **--help** +Print help (see a summary with -h) + +\<*RACK_ID*\> +Rack ID to show health history for + +## Examples + +```sh +nico-admin-cli rack health-history ipp6-b03-gb-nvl-124-mini2 +``` + +--- + +**See also:** [Hardware commands](../../hardware.md) · [CLI reference index](../../README.md) diff --git a/docs/manuals/nico-admin-cli/commands/rack/rack.md b/docs/manuals/nico-admin-cli/commands/rack/rack.md index b9c76964bd..d8db95600b 100644 --- a/docs/manuals/nico-admin-cli/commands/rack/rack.md +++ b/docs/manuals/nico-admin-cli/commands/rack/rack.md @@ -49,6 +49,7 @@ Print help (see a summary with -h) | [`profile`](./rack-profile.md) | Rack profile | | [`maintenance`](./rack-maintenance.md) | On-demand rack maintenance | | [`state-history`](./rack-state-history.md) | Show rack state history | +| [`health-history`](./rack-health-history.md) | Show rack health history | --- diff --git a/docs/manuals/nico-admin-cli/commands/switch/switch-health-history.md b/docs/manuals/nico-admin-cli/commands/switch/switch-health-history.md new file mode 100644 index 0000000000..3e18e4b8a9 --- /dev/null +++ b/docs/manuals/nico-admin-cli/commands/switch/switch-health-history.md @@ -0,0 +1,51 @@ +# `nico-admin-cli switch health-history` + +_[Hardware commands](../../hardware.md) › [switch](./switch.md) › **health-history**_ + +## NAME + +nico-admin-cli-switch-health-history - Show switch health history + +## SYNOPSIS + +**nico-admin-cli switch health-history** \[**--extended**\] +\[**--sort-by**\] \[**-h**\|**--help**\] \<*SWITCH_ID*\> + +## DESCRIPTION + +Show switch health history + +## OPTIONS + +**--extended** +Extended result output. + +This used by measured boot, where basic output contains just what you +probably care about, and "extended" output also dumps out all the +internal UUIDs that are used to associate instances. + +**--sort-by** *\* \[default: primary-id\] +Sort output by specified field\ + +\ +*Possible values:* + +- primary-id: Sort by the primary ID + +- state: Sort by state + +**-h**, **--help** +Print help (see a summary with -h) + +\<*SWITCH_ID*\> +Switch ID to show health history for + +## Examples + +```sh +nico-admin-cli switch health-history sw100nt038bg3qsho433vkg684heguv282qaggmrsh2ugn1qk096n2c6hcg +``` + +--- + +**See also:** [Hardware commands](../../hardware.md) · [CLI reference index](../../README.md) diff --git a/docs/manuals/nico-admin-cli/commands/switch/switch.md b/docs/manuals/nico-admin-cli/commands/switch/switch.md index 30b0adb226..dac15b5bca 100644 --- a/docs/manuals/nico-admin-cli/commands/switch/switch.md +++ b/docs/manuals/nico-admin-cli/commands/switch/switch.md @@ -46,6 +46,7 @@ Print help (see a summary with -h) | [`force-delete`](./switch-force-delete.md) | Force delete a switch and optionally its interfaces | | [`metadata`](./switch-metadata.md) | Manage Switch Metadata | | [`health-report`](./switch-health-report.md) | Manage health report sources | +| [`health-history`](./switch-health-history.md) | Show switch health history | ---