nv_redfish/computer_system/
item.rs1use crate::hardware_id::HardwareIdRef;
17use crate::hardware_id::Manufacturer as HardwareIdManufacturer;
18use crate::hardware_id::Model as HardwareIdModel;
19use crate::hardware_id::PartNumber as HardwareIdPartNumber;
20use crate::hardware_id::SerialNumber as HardwareIdSerialNumber;
21use crate::patch_support::Payload;
22use crate::patch_support::ReadPatchFn;
23use crate::resource::PowerState;
24use crate::schema::redfish::computer_system::ComputerSystem as ComputerSystemSchema;
25use crate::Error;
26use crate::NvBmc;
27use crate::Resource;
28use crate::ResourceSchema;
29use nv_redfish_core::Bmc;
30use nv_redfish_core::NavProperty;
31use std::convert::identity;
32use std::sync::Arc;
33use tagged_types::TaggedType;
34
35#[cfg(feature = "bios")]
36use crate::computer_system::Bios;
37#[cfg(feature = "boot-options")]
38use crate::computer_system::BootOptionCollection;
39#[cfg(feature = "memory")]
40use crate::computer_system::Memory;
41#[cfg(feature = "processors")]
42use crate::computer_system::Processor;
43#[cfg(feature = "secure-boot")]
44use crate::computer_system::SecureBoot;
45#[cfg(feature = "storages")]
46use crate::computer_system::Storage;
47#[cfg(feature = "ethernet-interfaces")]
48use crate::ethernet_interface::EthernetInterfaceCollection;
49#[cfg(feature = "log-services")]
50use crate::log_service::LogService;
51#[cfg(feature = "oem-lenovo")]
52use crate::oem::lenovo::computer_system::LenovoComputerSystem;
53#[cfg(feature = "oem-nvidia-bluefield")]
54use crate::oem::nvidia::bluefield::nvidia_computer_system::NvidiaComputerSystem;
55
56#[doc(hidden)]
57pub enum ComputerSystemTag {}
58
59pub type Manufacturer<T> = HardwareIdManufacturer<T, ComputerSystemTag>;
61
62pub type Model<T> = HardwareIdModel<T, ComputerSystemTag>;
64
65pub type PartNumber<T> = HardwareIdPartNumber<T, ComputerSystemTag>;
67
68pub type SerialNumber<T> = HardwareIdSerialNumber<T, ComputerSystemTag>;
70
71pub type Sku<T> = TaggedType<T, ComputerSystemSkuTag>;
73#[doc(hidden)]
74#[derive(tagged_types::Tag)]
75#[implement(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
76#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
77#[capability(inner_access, cloned)]
78pub enum ComputerSystemSkuTag {}
79
80pub type BootOptionReference<T> = TaggedType<T, BootOptionReferenceTag>;
82#[doc(hidden)]
83#[derive(tagged_types::Tag)]
84#[implement(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
85#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
86#[capability(inner_access, cloned)]
87pub enum BootOptionReferenceTag {}
88
89pub struct ComputerSystem<B: Bmc> {
93 #[allow(dead_code)] bmc: NvBmc<B>,
95 data: Arc<ComputerSystemSchema>,
96}
97
98impl<B: Bmc> ComputerSystem<B> {
99 pub(crate) async fn new(
101 bmc: &NvBmc<B>,
102 nav: &NavProperty<ComputerSystemSchema>,
103 read_patch_fn: Option<&ReadPatchFn>,
104 ) -> Result<Self, Error<B>> {
105 if let Some(read_patch_fn) = read_patch_fn {
106 Payload::get(bmc.as_ref(), nav, read_patch_fn.as_ref()).await
107 } else {
108 nav.get(bmc.as_ref()).await.map_err(Error::Bmc)
109 }
110 .map(|data| Self {
111 bmc: bmc.clone(),
112 data,
113 })
114 }
115
116 #[must_use]
121 pub fn raw(&self) -> Arc<ComputerSystemSchema> {
122 self.data.clone()
123 }
124
125 #[must_use]
127 pub fn hardware_id(&self) -> HardwareIdRef<'_, ComputerSystemTag> {
128 HardwareIdRef {
129 manufacturer: self
130 .data
131 .manufacturer
132 .as_ref()
133 .and_then(Option::as_deref)
134 .map(Manufacturer::new),
135 model: self
136 .data
137 .model
138 .as_ref()
139 .and_then(Option::as_deref)
140 .map(Model::new),
141 part_number: self
142 .data
143 .part_number
144 .as_ref()
145 .and_then(Option::as_deref)
146 .map(PartNumber::new),
147 serial_number: self
148 .data
149 .serial_number
150 .as_ref()
151 .and_then(Option::as_deref)
152 .map(SerialNumber::new),
153 }
154 }
155
156 #[must_use]
158 pub fn sku(&self) -> Option<Sku<&str>> {
159 self.data
160 .sku
161 .as_ref()
162 .and_then(Option::as_ref)
163 .map(String::as_str)
164 .map(Sku::new)
165 }
166
167 #[must_use]
169 pub fn power_state(&self) -> Option<PowerState> {
170 self.data.power_state.and_then(identity)
171 }
172
173 #[must_use]
176 pub fn boot_order(&self) -> Option<Vec<BootOptionReference<&str>>> {
177 self.data
178 .as_ref()
179 .boot
180 .as_ref()
181 .and_then(|boot| boot.boot_order.as_ref().and_then(Option::as_ref))
182 .map(|v| {
183 v.iter()
184 .map(String::as_str)
185 .map(BootOptionReference::new)
186 .collect::<Vec<_>>()
187 })
188 }
189
190 #[cfg(feature = "bios")]
198 pub async fn bios(&self) -> Result<Option<Bios<B>>, Error<B>> {
199 if let Some(bios_ref) = &self.data.bios {
200 Bios::new(&self.bmc, bios_ref).await.map(Some)
201 } else {
202 Ok(None)
203 }
204 }
205
206 #[cfg(feature = "processors")]
215 pub async fn processors(&self) -> Result<Option<Vec<Processor<B>>>, Error<B>> {
216 if let Some(processors_ref) = &self.data.processors {
217 let processors_collection = self.bmc.expand_property(processors_ref).await?;
218
219 let mut processors = Vec::new();
220 for m in &processors_collection.members {
221 processors.push(Processor::new(&self.bmc, m).await?);
222 }
223
224 Ok(Some(processors))
225 } else {
226 Ok(None)
227 }
228 }
229
230 #[cfg(feature = "secure-boot")]
238 pub async fn secure_boot(&self) -> Result<Option<SecureBoot<B>>, Error<B>> {
239 if let Some(secure_boot_ref) = &self.data.secure_boot {
240 SecureBoot::new(&self.bmc, secure_boot_ref).await.map(Some)
241 } else {
242 Ok(None)
243 }
244 }
245
246 #[cfg(feature = "storages")]
255 pub async fn storage_controllers(&self) -> Result<Option<Vec<Storage<B>>>, Error<B>> {
256 if let Some(storage_ref) = &self.data.storage {
257 let storage_collection = self.bmc.expand_property(storage_ref).await?;
258
259 let mut storage_controllers = Vec::new();
260 for m in &storage_collection.members {
261 storage_controllers.push(Storage::new(&self.bmc, m).await?);
262 }
263
264 Ok(Some(storage_controllers))
265 } else {
266 Ok(None)
267 }
268 }
269
270 #[cfg(feature = "memory")]
279 pub async fn memory_modules(&self) -> Result<Option<Vec<Memory<B>>>, Error<B>> {
280 if let Some(memory_ref) = &self.data.memory {
281 let memory_collection = self.bmc.expand_property(memory_ref).await?;
282
283 let mut memory_modules = Vec::new();
284 for m in &memory_collection.members {
285 memory_modules.push(Memory::new(&self.bmc, m).await?);
286 }
287
288 Ok(Some(memory_modules))
289 } else {
290 Ok(None)
291 }
292 }
293
294 #[cfg(feature = "log-services")]
302 pub async fn log_services(&self) -> Result<Option<Vec<LogService<B>>>, Error<B>> {
303 if let Some(log_services_ref) = &self.data.log_services {
304 let log_services_collection = log_services_ref
305 .get(self.bmc.as_ref())
306 .await
307 .map_err(Error::Bmc)?;
308
309 let mut log_services = Vec::new();
310 for m in &log_services_collection.members {
311 log_services.push(LogService::new(&self.bmc, m).await?);
312 }
313
314 Ok(Some(log_services))
315 } else {
316 Ok(None)
317 }
318 }
319
320 #[cfg(feature = "ethernet-interfaces")]
328 pub async fn ethernet_interfaces(
329 &self,
330 ) -> Result<Option<EthernetInterfaceCollection<B>>, Error<B>> {
331 if let Some(p) = &self.data.ethernet_interfaces {
332 EthernetInterfaceCollection::new(&self.bmc, p)
333 .await
334 .map(Some)
335 } else {
336 Ok(None)
337 }
338 }
339
340 #[cfg(feature = "boot-options")]
348 pub async fn boot_options(&self) -> Result<Option<BootOptionCollection<B>>, Error<B>> {
349 if let Some(p) = &self
350 .data
351 .boot
352 .as_ref()
353 .and_then(|v| v.boot_options.as_ref())
354 {
355 BootOptionCollection::new(&self.bmc, p).await.map(Some)
356 } else {
357 Ok(None)
358 }
359 }
360
361 #[cfg(feature = "oem-nvidia-bluefield")]
369 pub async fn oem_nvidia_bluefield(&self) -> Result<Option<NvidiaComputerSystem<B>>, Error<B>> {
370 if let Some(oem) = self.data.base.base.oem.as_ref() {
371 NvidiaComputerSystem::new(&self.bmc, oem).await
372 } else {
373 Ok(None)
374 }
375 }
376
377 #[cfg(feature = "oem-lenovo")]
385 pub fn oem_lenovo(&self) -> Result<Option<LenovoComputerSystem<B>>, Error<B>> {
386 LenovoComputerSystem::new(&self.bmc, &self.data)
387 }
388}
389
390impl<B: Bmc> Resource for ComputerSystem<B> {
391 fn resource_ref(&self) -> &ResourceSchema {
392 &self.data.as_ref().base
393 }
394}