use std::collections::HashMap;
use std::fmt;
use model::{OData, ODataId};
use serde::{Deserialize, Serialize};
use crate::model;
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct ServiceRoot {
#[serde(flatten)]
pub odata: OData,
pub product: Option<String>,
pub redfish_version: String,
pub vendor: Option<String>,
#[serde(rename = "UUID")]
pub uuid: Option<String>,
pub oem: Option<HashMap<String, serde_json::Value>>,
pub update_service: Option<HashMap<String, serde_json::Value>>,
pub account_service: Option<ODataId>,
pub certificate_service: Option<ODataId>,
pub chassis: Option<ODataId>,
pub component_integrity: Option<ODataId>,
pub event_service: Option<ODataId>,
pub license_service: Option<ODataId>,
pub fabrics: Option<ODataId>,
pub managers: Option<ODataId>,
pub session_service: Option<ODataId>,
pub systems: Option<ODataId>,
pub tasks: Option<ODataId>,
pub telemetry_service: Option<ODataId>,
}
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq, Serialize, Deserialize)]
pub enum RedfishVendor {
Lenovo,
Dell,
NvidiaDpu,
Supermicro,
AMI, Hpe,
NvidiaGH200, NvidiaGBx00, NvidiaGBSwitch, P3809, LiteOnPowerShelf,
Unknown,
}
impl fmt::Display for RedfishVendor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
impl ServiceRoot {
pub fn vendor_string(&self) -> Option<String> {
self.vendor.as_ref().cloned().or_else(|| match &self.oem {
Some(oem) => oem.keys().next().cloned(),
None => None,
})
}
pub fn vendor(&self) -> Option<RedfishVendor> {
let v = self.vendor_string().unwrap_or("Unknown".to_string());
Some(match v.to_lowercase().as_str() {
"ami" => RedfishVendor::AMI,
"dell" => RedfishVendor::Dell,
"hpe" => RedfishVendor::Hpe,
"lenovo" => RedfishVendor::Lenovo,
"nvidia" => match self.product.as_deref() {
Some("P3809") => RedfishVendor::P3809, Some("GB200 NVL") => RedfishVendor::NvidiaGBx00,
_ => RedfishVendor::NvidiaDpu,
},
"wiwynn" => RedfishVendor::NvidiaGBx00,
"supermicro" => RedfishVendor::Supermicro,
"lite-on technology corp." => RedfishVendor::LiteOnPowerShelf,
_ => RedfishVendor::Unknown,
})
}
pub fn has_ami_bmc(&self) -> bool {
self.oem
.as_ref()
.map(|oem| oem.keys().any(|k| k.to_lowercase() == "ami"))
.unwrap_or(false)
}
}
#[cfg(test)]
mod test {
use crate::model::service_root::RedfishVendor;
#[test]
fn test_supermicro_service_root() {
let data = include_str!("testdata/supermicro_service_root.json");
let result: super::ServiceRoot = serde_json::from_str(data).unwrap();
assert_eq!(result.vendor().unwrap(), RedfishVendor::Supermicro);
}
}