Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/bmc-mock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ tracing-subscriber = { features = ["env-filter"], workspace = true }
url = { workspace = true }

[dev-dependencies]
carbide-test-support = { path = "../test-support" }
tokio = { features = ["test-util"], workspace = true }

[lints]
Expand Down
8 changes: 4 additions & 4 deletions crates/bmc-mock/src/auth_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use crate::redfish::{account_service, service_root, session_service};
const WWW_AUTHENTICATE_VALUE: HeaderValue = HeaderValue::from_static("Basic realm=\"bmc-mock\"");
const X_AUTH_TOKEN_HEADER: &str = "x-auth-token";

pub fn append(router: Router, authorizer: Authorizer) -> Router {
pub(super) fn append(router: Router, authorizer: Authorizer) -> Router {
let service_root_path = service_root::resource().odata_id.to_string();
let service_root_path_with_trailing_slash = format!("{service_root_path}/");
let account_service_path = account_service::resource().odata_id.to_string();
Expand Down Expand Up @@ -162,15 +162,15 @@ impl AuthMiddleware {
}

#[derive(Clone)]
pub struct Authorizer {
pub(super) struct Authorizer {
account_service_state: Arc<AccountServiceState>,
session_service_state: Arc<SessionServiceState>,
forbid_factory_default_password: bool,
}

impl Authorizer {
/// Builds the factory-default authorizer for a mock BMC state.
pub fn new(
pub(super) fn new(
account_service_state: Arc<AccountServiceState>,
session_service_state: Arc<SessionServiceState>,
) -> Self {
Expand All @@ -181,7 +181,7 @@ impl Authorizer {
}
}

pub fn permit_factory_default_password(mut self) -> Self {
pub(super) fn permit_factory_default_password(mut self) -> Self {
self.forbid_factory_default_password = false;
self
}
Expand Down
20 changes: 10 additions & 10 deletions crates/bmc-mock/src/bmc_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@ use crate::redfish::update_service::UpdateServiceState;

#[derive(Clone)]
pub struct BmcState {
pub bmc_vendor: redfish::oem::BmcVendor,
pub bmc_product: Option<&'static str>,
pub bmc_redfish_version: &'static str,
pub oem_state: redfish::oem::State,
pub(crate) bmc_vendor: redfish::oem::BmcVendor,
pub(crate) bmc_product: Option<&'static str>,
pub(crate) bmc_redfish_version: &'static str,
pub(crate) oem_state: redfish::oem::State,
pub manager: Arc<ManagerState>,
pub system_state: Arc<SystemState>,
pub chassis_state: Arc<ChassisState>,
pub update_service_state: Arc<UpdateServiceState>,
pub(crate) chassis_state: Arc<ChassisState>,
pub(crate) update_service_state: Arc<UpdateServiceState>,
pub account_service_state: Arc<AccountServiceState>,
pub session_service_state: Arc<SessionServiceState>,
pub(crate) session_service_state: Arc<SessionServiceState>,
pub injection: Arc<InjectionStore>,
pub callbacks: Option<Arc<dyn crate::Callbacks>>,
pub(crate) callbacks: Option<Arc<dyn crate::Callbacks>>,
/// Whether this BMC advertises and serves the `/redfish/v1/Systems`
/// collection. Delta power shelves expose no `ComputerSystem` collection,
/// so the service root omits the `Systems` link and the collection endpoint
/// returns 404.
pub exposes_computer_systems: bool,
pub(crate) exposes_computer_systems: bool,
}

#[derive(Clone, Copy, Debug)]
Expand All @@ -65,7 +65,7 @@ impl BmcState {
}
}

pub fn complete_all_bios_jobs(&self) {
fn complete_all_bios_jobs(&self) {
if let redfish::oem::State::DellIdrac(v) = &self.oem_state {
v.complete_all_bios_jobs()
}
Expand Down
42 changes: 21 additions & 21 deletions crates/bmc-mock/src/command_line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ use bmc_mock::HardwareType;
use clap::{Parser, ValueEnum};

#[derive(Clone, Copy, Debug, Eq, PartialEq, ValueEnum)]
pub enum MachineRole {
pub(super) enum MachineRole {
Host,
Dpu,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, ValueEnum)]
pub enum StateBackend {
pub(super) enum StateBackend {
Internal,
Libvirt,
}
Expand All @@ -47,9 +47,9 @@ fn parse_hardware_profile(value: &str) -> Result<HardwareType, String> {
}

#[derive(Clone, Parser, Debug)]
pub struct IpRouterPair {
pub ip_address: String,
pub targz: std::path::PathBuf,
pub(super) struct IpRouterPair {
pub(super) ip_address: String,
pub(super) targz: std::path::PathBuf,
}

impl From<String> for IpRouterPair {
Expand All @@ -67,77 +67,77 @@ impl From<String> for IpRouterPair {
}

#[derive(Clone, Parser, Debug)]
pub struct Args {
pub(super) struct Args {
#[clap(short, long)]
pub cert_path: Option<String>,
pub(super) cert_path: Option<String>,

#[clap(short, long)]
pub port: Option<u16>,
pub(super) port: Option<u16>,

#[clap(
long,
help = "Path to .tar.gz file of redfish data to output. Create it from libredfish tests/mockups/<vendor>"
)]
pub targz: Option<std::path::PathBuf>,
pub(super) targz: Option<std::path::PathBuf>,

#[clap(
long,
help = "An ip_address and .tar.gz file pair (comma separated).\nThe file is an archive of redfish data when the request is forwarded to a specific IP address.\nRepeat for different machines"
)]
pub ip_router: Option<Vec<IpRouterPair>>,
pub(super) ip_router: Option<Vec<IpRouterPair>>,

#[clap(long, help = "Start an IPMI/SOL simulator for the generated BMC mock")]
pub enable_ipmi_simulation: bool,
pub(super) enable_ipmi_simulation: bool,

#[clap(long, help = "Back the generated BMC with the named libvirt domain")]
pub libvirt_domain: Option<String>,
pub(super) libvirt_domain: Option<String>,

#[clap(
long,
value_parser = parse_hardware_profile,
help = "Redfish hardware profile for an explicitly configured host or DPU, using its existing snake_case name"
)]
pub hardware_profile: Option<HardwareType>,
pub(super) hardware_profile: Option<HardwareType>,

#[clap(long, value_enum, help = "Expose a host BMC or one DPU BMC")]
pub machine_role: Option<MachineRole>,
pub(super) machine_role: Option<MachineRole>,

#[clap(
long,
value_enum,
help = "Use an in-process power-state simulator or a libvirt domain"
)]
pub state_backend: Option<StateBackend>,
pub(super) state_backend: Option<StateBackend>,

#[clap(
long,
requires = "hardware_profile",
help = "DPU count for a variable-count profile, or an assertion for a fixed-count profile"
)]
pub dpu_count: Option<u8>,
pub(super) dpu_count: Option<u8>,

#[clap(
long,
requires = "hardware_profile",
help = "Zero-based DPU index when --machine-role=dpu"
)]
pub dpu_index: Option<usize>,
pub(super) dpu_index: Option<usize>,

#[clap(
long,
default_value_t = 0,
help = "Stable instance number used to make generated identities unique"
)]
pub instance_index: u8,
pub(super) instance_index: u8,

#[clap(long, default_value = "qemu:///system", requires = "libvirt_domain")]
pub libvirt_uri: String,
pub(super) libvirt_uri: String,

#[clap(long, default_value = "virsh", requires = "libvirt_domain")]
pub virsh_path: PathBuf,
pub(super) virsh_path: PathBuf,
}

pub fn parse_args() -> Args {
pub(super) fn parse_args() -> Args {
Args::parse()
}

Expand Down
43 changes: 22 additions & 21 deletions crates/bmc-mock/src/hw/bluefield3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,27 @@ use serde_json::json;

use crate::{BootOptionKind, Callbacks, LogService, LogServices, hw, redfish};

pub struct Bluefield3<'a> {
pub product_serial_number: Cow<'a, str>,
pub host_mac_address: MacAddress,
pub bmc_mac_address: MacAddress,
pub oob_mac_address: Option<MacAddress>,
pub mode: Mode,
pub firmware_versions: FirmwareVersions,
pub(crate) struct Bluefield3<'a> {
pub(crate) product_serial_number: Cow<'a, str>,
pub(crate) host_mac_address: MacAddress,
pub(crate) bmc_mac_address: MacAddress,
pub(crate) oob_mac_address: Option<MacAddress>,
pub(crate) mode: Mode,
pub(crate) firmware_versions: FirmwareVersions,
}

pub enum Mode {
pub(crate) enum Mode {
// P/N 900-9D3B6-00CN-PA0. Installed on WIWYNN GB200s / Lenovo GB300s.
B3240ColdAisle,
// P/N 900-9D3B4-00CC-EA0 & 900-9D3B6-00CV-AA0
SuperNIC { nic_mode: bool },
}

pub struct FirmwareVersions {
pub bmc: String,
pub uefi: String,
pub dpu_nic: String,
pub erot: String,
pub(crate) struct FirmwareVersions {
pub(crate) bmc: String,
pub(crate) uefi: String,
pub(crate) dpu_nic: String,
pub(crate) erot: String,
}

impl Bluefield3<'_> {
Expand All @@ -57,7 +57,7 @@ impl Bluefield3<'_> {
}
}

pub fn chassis_config(&self) -> redfish::chassis::ChassisConfig {
pub(crate) fn chassis_config(&self) -> redfish::chassis::ChassisConfig {
redfish::chassis::ChassisConfig {
chassis: vec![
redfish::chassis::SingleChassisConfig {
Expand Down Expand Up @@ -108,7 +108,10 @@ impl Bluefield3<'_> {
}
}

pub fn system_config(&self, callbacks: Arc<dyn Callbacks>) -> redfish::computer_system::Config {
pub(crate) fn system_config(
&self,
callbacks: Arc<dyn Callbacks>,
) -> redfish::computer_system::Config {
let system_id = "Bluefield";
let boot_opt_builder = |id: &str, kind| {
redfish::boot_option::builder(&redfish::boot_option::resource(system_id, id), kind)
Expand Down Expand Up @@ -188,7 +191,7 @@ impl Bluefield3<'_> {
}
}

pub fn manager_config(&self) -> redfish::manager::Config {
pub(crate) fn manager_config(&self) -> redfish::manager::Config {
redfish::manager::Config {
managers: vec![redfish::manager::SingleConfig {
id: "Bluefield_BMC",
Expand All @@ -208,7 +211,7 @@ impl Bluefield3<'_> {
}
}

pub fn update_service_config(&self) -> redfish::update_service::UpdateServiceConfig {
pub(crate) fn update_service_config(&self) -> redfish::update_service::UpdateServiceConfig {
let base_mac = self.base_mac().to_string().replace(':', "");
let sys_image = format!(
"{}:{}00:00{}:{}",
Expand Down Expand Up @@ -237,7 +240,7 @@ impl Bluefield3<'_> {
}
}

pub fn host_nic(&self) -> hw::nic::Nic<'static> {
pub(crate) fn host_nic(&self) -> hw::nic::Nic<'static> {
hw::nic::Nic {
mac_address: self.host_mac_address,
// This how it represented on host with number of trailing
Expand All @@ -250,11 +253,10 @@ impl Bluefield3<'_> {
),
part_number: Some(self.part_number().into()),
firmware_version: Some(self.firmware_versions.dpu_nic.clone().into()),
is_mat_dpu: true,
}
}

pub fn host_nic_h100_variant(&self) -> hw::nic::Nic<'static> {
pub(super) fn host_nic_h100_variant(&self) -> hw::nic::Nic<'static> {
hw::nic::Nic {
mac_address: self.host_mac_address,
// This how it represented on host with number of trailing
Expand All @@ -265,7 +267,6 @@ impl Bluefield3<'_> {
description: None,
part_number: Some(format!("{} ", self.part_number()).into()),
firmware_version: Some(self.firmware_versions.dpu_nic.clone().into()),
is_mat_dpu: true,
}
}

Expand Down
Loading
Loading