nv_redfish/computer_system/
mod.rs1mod item;
22
23#[cfg(feature = "bios")]
24pub mod bios;
25#[cfg(feature = "boot-options")]
26pub mod boot_option;
27#[cfg(feature = "storages")]
28pub mod drive;
29#[cfg(feature = "memory")]
30pub mod memory;
31#[cfg(feature = "processors")]
32pub mod processor;
33#[cfg(feature = "secure-boot")]
34pub mod secure_boot;
35#[cfg(feature = "storages")]
36pub mod storage;
37
38use crate::patch_support::CollectionWithPatch;
39use crate::patch_support::FilterFn;
40use crate::patch_support::JsonValue;
41use crate::patch_support::ReadPatchFn;
42use crate::resource::Resource as _;
43use crate::schema::redfish::computer_system::ComputerSystem as ComputerSystemSchema;
44use crate::schema::redfish::computer_system_collection::ComputerSystemCollection as ComputerSystemCollectionSchema;
45use crate::schema::redfish::resource::ResourceCollection;
46use crate::Error;
47use crate::NvBmc;
48use crate::ServiceRoot;
49use nv_redfish_core::Bmc;
50use nv_redfish_core::NavProperty;
51use std::convert::identity;
52use std::sync::Arc;
53
54#[doc(inline)]
55pub use item::BootOptionReference;
56#[doc(inline)]
57pub use item::ComputerSystem;
58
59#[doc(inline)]
60#[cfg(feature = "bios")]
61pub use bios::Bios;
62#[doc(inline)]
63#[cfg(feature = "boot-options")]
64pub use boot_option::BootOption;
65#[doc(inline)]
66#[cfg(feature = "boot-options")]
67pub use boot_option::BootOptionCollection;
68#[doc(inline)]
69#[cfg(feature = "storages")]
70pub use drive::Drive;
71#[doc(inline)]
72#[cfg(feature = "memory")]
73pub use memory::Memory;
74#[doc(inline)]
75#[cfg(feature = "processors")]
76pub use processor::Processor;
77#[doc(inline)]
78#[cfg(feature = "secure-boot")]
79pub use secure_boot::SecureBoot;
80#[doc(inline)]
81#[cfg(feature = "secure-boot")]
82pub use secure_boot::SecureBootCurrentBootType;
83#[doc(inline)]
84#[cfg(feature = "storages")]
85pub use storage::Storage;
86
87pub struct SystemCollection<B: Bmc> {
91 bmc: NvBmc<B>,
92 collection: Arc<ComputerSystemCollectionSchema>,
93 read_patch_fn: Option<ReadPatchFn>,
94}
95
96impl<B: Bmc> SystemCollection<B> {
97 pub(crate) async fn new(
98 bmc: &NvBmc<B>,
99 root: &ServiceRoot<B>,
100 ) -> Result<Option<Self>, Error<B>> {
101 let mut patches = Vec::new();
102 let mut filters = Vec::new();
103 if let Some(odata_id_filter) = bmc.quirks.filter_computer_system_odata_ids() {
104 filters.push(Box::new(move |js: &JsonValue| {
105 js.get("@odata.id")
106 .and_then(|v| v.as_str())
107 .map(odata_id_filter)
108 .is_some_and(identity)
109 }));
110 }
111 if bmc.quirks.computer_systems_wrong_last_reset_time() {
112 patches.push(computer_systems_wrong_last_reset_time);
113 }
114 let read_patch_fn = (!patches.is_empty())
115 .then(|| Arc::new(move |v| patches.iter().fold(v, |acc, f| f(acc))) as ReadPatchFn);
116 let filters_fn = (!filters.is_empty())
117 .then(move || Arc::new(move |v: &JsonValue| filters.iter().any(|f| f(v))) as FilterFn);
118
119 if let Some(collection_ref) = &root.root.systems {
120 Self::expand_collection(
121 bmc,
122 collection_ref,
123 read_patch_fn.as_ref(),
124 filters_fn.as_ref(),
125 )
126 .await
127 .map(Some)
128 } else if bmc.quirks.bug_missing_root_nav_properties() {
129 bmc.expand_property(&NavProperty::new_reference(
130 format!("{}/Systems", root.odata_id()).into(),
131 ))
132 .await
133 .map(Some)
134 } else {
135 Ok(None)
136 }
137 .map(|c| {
138 c.map(|collection| Self {
139 bmc: bmc.clone(),
140 collection,
141 read_patch_fn,
142 })
143 })
144 }
145
146 pub async fn members(&self) -> Result<Vec<ComputerSystem<B>>, Error<B>> {
152 let mut members = Vec::new();
153 for m in &self.collection.members {
154 members.push(ComputerSystem::new(&self.bmc, m, self.read_patch_fn.as_ref()).await?);
155 }
156 Ok(members)
157 }
158}
159
160impl<B: Bmc> CollectionWithPatch<ComputerSystemCollectionSchema, ComputerSystemSchema, B>
161 for SystemCollection<B>
162{
163 fn convert_patched(
164 base: ResourceCollection,
165 members: Vec<NavProperty<ComputerSystemSchema>>,
166 ) -> ComputerSystemCollectionSchema {
167 ComputerSystemCollectionSchema { base, members }
168 }
169}
170
171fn computer_systems_wrong_last_reset_time(v: JsonValue) -> JsonValue {
175 if let JsonValue::Object(mut obj) = v {
176 if let Some(JsonValue::String(date)) = obj.get("LastResetTime") {
177 if date.starts_with("0000-00-00") {
178 obj.remove("LastResetTime");
179 }
180 }
181 JsonValue::Object(obj)
182 } else {
183 v
184 }
185}