Skip to content
Merged
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
72 changes: 57 additions & 15 deletions src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,51 @@ impl RedfishClientPool {
.await
}

/// Creates a Redfish BMC client for a certain endpoint and adds custom headers to subsequent requests.
/// Creates a Redfish BMC client for a certain endpoint,
/// and adds custom headers to subsequent requests.
///
/// Creating the client will immediately start a HTTP requests
/// to set system_id, manager_id and vendor type.
/// `custom_headers` will be added to any headers used by vendor specific implementations or the http client.
/// Creating the client will immediately start HTTP requests
/// to set system_id, manager_id, and vendor type (the vendor
/// is auto-detected from the service root.
///
/// `custom_headers` will be added to any headers used by vendor
/// specific implementations or the http client.
pub async fn create_client_with_custom_headers(
&self,
endpoint: Endpoint,
custom_headers: Vec<(HeaderName, String)>,
) -> Result<Box<dyn crate::Redfish>, RedfishError> {
self.create_client_impl(endpoint, None, custom_headers)
.await
}

/// Creates a Redfish BMC client for a certain endpoint using
/// the provided vendor instead of auto-detecting from the service
/// root. This is needed for BMCs (e.g. Lite-On power shelves) whose
/// service root does not expose vendor information, where we need
/// a client that uses vendor-specific logic.
pub async fn create_client_with_vendor(
&self,
endpoint: Endpoint,
vendor: RedfishVendor,
custom_headers: Vec<(HeaderName, String)>,
) -> Result<Box<dyn crate::Redfish>, RedfishError> {
self.create_client_impl(endpoint, Some(vendor), custom_headers)
.await
}

// Creates a complete "client" that takes the endpoint, an optional
// vendor (which falls back to self-detection using the service root),
// and an optional set of custom headers.
//
// If there's ever a need to expose this as pub, it's entirely
// reasonable to do so (and rename it to something descriptive like
// create_complete_client).
async fn create_client_impl(
&self,
endpoint: Endpoint,
vendor: Option<RedfishVendor>,
custom_headers: Vec<(HeaderName, String)>,
) -> Result<Box<dyn crate::Redfish>, RedfishError> {
let client = RedfishHttpClient::new(self.http_client.clone(), endpoint, custom_headers);
let mut s = RedfishStandard::new(client);
Expand All @@ -172,22 +208,28 @@ impl RedfishClientPool {
})?;
let chassis = s.get_chassis_all().await?;

s.set_system_id(system_id)?;
// call set_system_id always before calling set_vendor
s.set_system_id(system_id)?;
s.set_manager_id(manager_id)?;
s.set_service_root(service_root.clone())?;

let Some(mut vendor) = service_root.vendor() else {
return Err(RedfishError::MissingVendor);
};
if vendor == RedfishVendor::P3809 {
if chassis.contains(&"MGX_NVSwitch_0".to_string()) {
vendor = RedfishVendor::NvidiaGBSwitch;
} else {
vendor = RedfishVendor::NvidiaGH200;
let vendor = match vendor {
Some(v) => v,
None => {
let Some(mut v) = service_root.vendor() else {
return Err(RedfishError::MissingVendor);
};
if v == RedfishVendor::P3809 {
if chassis.contains(&"MGX_NVSwitch_0".to_string()) {
v = RedfishVendor::NvidiaGBSwitch;
} else {
v = RedfishVendor::NvidiaGH200;
}
}
v
}
}
// returns the vendor specific object
};

s.set_vendor(vendor).await
}

Expand Down
Loading