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-nvidia-bluefield")]
52use crate::oem::nvidia::bluefield::nvidia_computer_system::NvidiaComputerSystem;
53
54#[doc(hidden)]
55pub enum ComputerSystemTag {}
56
57pub type Manufacturer<T> = HardwareIdManufacturer<T, ComputerSystemTag>;
59
60pub type Model<T> = HardwareIdModel<T, ComputerSystemTag>;
62
63pub type PartNumber<T> = HardwareIdPartNumber<T, ComputerSystemTag>;
65
66pub type SerialNumber<T> = HardwareIdSerialNumber<T, ComputerSystemTag>;
68
69pub type Sku<T> = TaggedType<T, ComputerSystemSkuTag>;
71#[doc(hidden)]
72#[derive(tagged_types::Tag)]
73#[implement(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
74#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
75#[capability(inner_access, cloned)]
76pub enum ComputerSystemSkuTag {}
77
78pub type BootOptionReference<T> = TaggedType<T, BootOptionReferenceTag>;
80#[doc(hidden)]
81#[derive(tagged_types::Tag)]
82#[implement(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
83#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
84#[capability(inner_access, cloned)]
85pub enum BootOptionReferenceTag {}
86
87pub struct ComputerSystem<B: Bmc> {
91 #[allow(dead_code)] bmc: NvBmc<B>,
93 data: Arc<ComputerSystemSchema>,
94}
95
96impl<B: Bmc> ComputerSystem<B> {
97 pub(crate) async fn new(
99 bmc: &NvBmc<B>,
100 nav: &NavProperty<ComputerSystemSchema>,
101 read_patch_fn: Option<&ReadPatchFn>,
102 ) -> Result<Self, Error<B>> {
103 if let Some(read_patch_fn) = read_patch_fn {
104 Payload::get(bmc.as_ref(), nav, read_patch_fn.as_ref()).await
105 } else {
106 nav.get(bmc.as_ref()).await.map_err(Error::Bmc)
107 }
108 .map(|data| Self {
109 bmc: bmc.clone(),
110 data,
111 })
112 }
113
114 #[must_use]
119 pub fn raw(&self) -> Arc<ComputerSystemSchema> {
120 self.data.clone()
121 }
122
123 #[must_use]
125 pub fn hardware_id(&self) -> HardwareIdRef<'_, ComputerSystemTag> {
126 HardwareIdRef {
127 manufacturer: self
128 .data
129 .manufacturer
130 .as_ref()
131 .and_then(Option::as_ref)
132 .map(Manufacturer::new),
133 model: self
134 .data
135 .model
136 .as_ref()
137 .and_then(Option::as_ref)
138 .map(Model::new),
139 part_number: self
140 .data
141 .part_number
142 .as_ref()
143 .and_then(Option::as_ref)
144 .map(PartNumber::new),
145 serial_number: self
146 .data
147 .serial_number
148 .as_ref()
149 .and_then(Option::as_ref)
150 .map(SerialNumber::new),
151 }
152 }
153
154 #[must_use]
156 pub fn sku(&self) -> Option<Sku<&String>> {
157 self.data
158 .sku
159 .as_ref()
160 .and_then(Option::as_ref)
161 .map(Sku::new)
162 }
163
164 #[must_use]
166 pub fn power_state(&self) -> Option<PowerState> {
167 self.data.power_state.and_then(identity)
168 }
169
170 #[must_use]
173 pub fn boot_order(&self) -> Option<Vec<BootOptionReference<&String>>> {
174 self.data
175 .as_ref()
176 .boot
177 .as_ref()
178 .and_then(|boot| boot.boot_order.as_ref().and_then(Option::as_ref))
179 .map(|v| v.iter().map(BootOptionReference::new).collect::<Vec<_>>())
180 }
181
182 #[cfg(feature = "bios")]
192 pub async fn bios(&self) -> Result<Bios<B>, Error<B>> {
193 let bios_ref = self.data.bios.as_ref().ok_or(Error::BiosNotAvailable)?;
194 Bios::new(&self.bmc, bios_ref).await
195 }
196
197 #[cfg(feature = "processors")]
207 pub async fn processors(&self) -> Result<Vec<Processor<B>>, Error<B>> {
208 let processors_ref = self
209 .data
210 .processors
211 .as_ref()
212 .ok_or(Error::ProcessorsNotAvailable)?;
213
214 let processors_collection = self.bmc.expand_property(processors_ref).await?;
215
216 let mut processors = Vec::new();
217 for m in &processors_collection.members {
218 processors.push(Processor::new(&self.bmc, m).await?);
219 }
220
221 Ok(processors)
222 }
223
224 #[cfg(feature = "secure-boot")]
232 pub async fn secure_boot(&self) -> Result<SecureBoot<B>, Error<B>> {
233 let secure_boot_ref = self
234 .data
235 .secure_boot
236 .as_ref()
237 .ok_or(Error::SecureBootNotAvailable)?;
238 SecureBoot::new(&self.bmc, secure_boot_ref).await
239 }
240
241 #[cfg(feature = "storages")]
251 pub async fn storage_controllers(&self) -> Result<Vec<Storage<B>>, Error<B>> {
252 let storage_ref = self
253 .data
254 .storage
255 .as_ref()
256 .ok_or(Error::StorageNotAvailable)?;
257
258 let storage_collection = self.bmc.expand_property(storage_ref).await?;
259
260 let mut storage_controllers = Vec::new();
261 for m in &storage_collection.members {
262 storage_controllers.push(Storage::new(&self.bmc, m).await?);
263 }
264
265 Ok(storage_controllers)
266 }
267
268 #[cfg(feature = "memory")]
278 pub async fn memory_modules(&self) -> Result<Vec<Memory<B>>, Error<B>> {
279 let memory_ref = self.data.memory.as_ref().ok_or(Error::MemoryNotAvailable)?;
280
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(memory_modules)
289 }
290
291 #[cfg(feature = "log-services")]
299 pub async fn log_services(&self) -> Result<Vec<LogService<B>>, Error<B>> {
300 let log_services_ref = self
301 .data
302 .log_services
303 .as_ref()
304 .ok_or(Error::LogServiceNotAvailable)?;
305
306 let log_services_collection = log_services_ref
307 .get(self.bmc.as_ref())
308 .await
309 .map_err(Error::Bmc)?;
310
311 let mut log_services = Vec::new();
312 for m in &log_services_collection.members {
313 log_services.push(LogService::new(&self.bmc, m).await?);
314 }
315
316 Ok(log_services)
317 }
318
319 #[cfg(feature = "ethernet-interfaces")]
327 pub async fn ethernet_interfaces(&self) -> Result<EthernetInterfaceCollection<B>, Error<B>> {
328 let p = self
329 .data
330 .ethernet_interfaces
331 .as_ref()
332 .ok_or(Error::EthernetInterfacesNotAvailable)?;
333 EthernetInterfaceCollection::new(&self.bmc, p).await
334 }
335
336 #[cfg(feature = "boot-options")]
344 pub async fn boot_options(&self) -> Result<BootOptionCollection<B>, Error<B>> {
345 let p = self
346 .data
347 .boot
348 .as_ref()
349 .ok_or(Error::BootOptionsNotAvailable)?
350 .boot_options
351 .as_ref()
352 .ok_or(Error::BootOptionsNotAvailable)?;
353 BootOptionCollection::new(&self.bmc, p).await
354 }
355
356 #[cfg(feature = "oem-nvidia-bluefield")]
364 pub async fn oem_nvidia_bluefield(&self) -> Result<NvidiaComputerSystem<B>, Error<B>> {
365 let oem = self
366 .data
367 .base
368 .base
369 .oem
370 .as_ref()
371 .ok_or(Error::NvidiaComputerSystemNotAvailable)?;
372 NvidiaComputerSystem::new(&self.bmc, oem).await
373 }
374}
375
376impl<B: Bmc> Resource for ComputerSystem<B> {
377 fn resource_ref(&self) -> &ResourceSchema {
378 &self.data.as_ref().base
379 }
380}