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::computer_system::ComputerSystem as ComputerSystemSchema;
44use crate::schema::computer_system_collection::ComputerSystemCollection as ComputerSystemCollectionSchema;
45use crate::schema::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 as fn(JsonValue) -> JsonValue);
113 }
114 if bmc.quirks.bug_empty_uuid_field() {
115 patches.push(normalize_empty_uuid_field);
116 }
117 let read_patch_fn = (!patches.is_empty())
118 .then(|| Arc::new(move |v| patches.iter().fold(v, |acc, f| f(acc))) as ReadPatchFn);
119 let filters_fn = (!filters.is_empty())
120 .then(move || Arc::new(move |v: &JsonValue| filters.iter().any(|f| f(v))) as FilterFn);
121
122 if let Some(collection_ref) = &root.root.systems {
123 Self::expand_collection(
124 bmc,
125 collection_ref,
126 read_patch_fn.as_ref(),
127 filters_fn.as_ref(),
128 )
129 .await
130 .map(Some)
131 } else if bmc.quirks.bug_missing_root_nav_properties() {
132 bmc.expand_property(&NavProperty::new_reference(
133 format!("{}/Systems", root.odata_id()).into(),
134 ))
135 .await
136 .map(Some)
137 } else {
138 Ok(None)
139 }
140 .map(|c| {
141 c.map(|collection| Self {
142 bmc: bmc.clone(),
143 collection,
144 read_patch_fn,
145 })
146 })
147 }
148
149 pub async fn members(&self) -> Result<Vec<ComputerSystem<B>>, Error<B>> {
155 let mut members = Vec::new();
156 for m in &self.collection.members {
157 members.push(ComputerSystem::new(&self.bmc, m, self.read_patch_fn.as_ref()).await?);
158 }
159 Ok(members)
160 }
161}
162
163impl<B: Bmc> CollectionWithPatch<ComputerSystemCollectionSchema, ComputerSystemSchema, B>
164 for SystemCollection<B>
165{
166 fn convert_patched(
167 base: ResourceCollection,
168 members: Vec<NavProperty<ComputerSystemSchema>>,
169 ) -> ComputerSystemCollectionSchema {
170 ComputerSystemCollectionSchema { base, members }
171 }
172}
173
174fn computer_systems_wrong_last_reset_time(v: JsonValue) -> JsonValue {
178 if let JsonValue::Object(mut obj) = v {
179 if let Some(JsonValue::String(date)) = obj.get("LastResetTime") {
180 if date.starts_with("0000-00-00") {
181 obj.remove("LastResetTime");
182 }
183 }
184 JsonValue::Object(obj)
185 } else {
186 v
187 }
188}
189
190fn normalize_empty_uuid_field(mut v: JsonValue) -> JsonValue {
191 if let JsonValue::Object(ref mut obj) = v {
192 if let Some(uuid) = obj.get_mut("UUID") {
193 let is_empty = uuid.as_str().is_some_and(str::is_empty);
194 if is_empty {
195 *uuid = JsonValue::Null;
196 }
197 }
198 }
199 v
200}