nv_redfish/
service_root.rs1use crate::bmc_quirks::BmcQuirks;
17use crate::core::Bmc;
18use crate::core::NavProperty;
19use crate::core::ODataId;
20use crate::schema::service_root::ServiceRoot as SchemaServiceRoot;
21use crate::Error;
22use crate::NvBmc;
23use crate::ProtocolFeatures;
24use crate::Resource;
25use crate::ResourceSchema;
26use std::sync::Arc;
27use tagged_types::TaggedType;
28
29#[cfg(feature = "accounts")]
30use crate::account::AccountService;
31#[cfg(feature = "chassis")]
32use crate::chassis::ChassisCollection;
33#[cfg(feature = "chassis")]
34use crate::chassis::ChassisLink;
35#[cfg(feature = "computer-systems")]
36use crate::computer_system::SystemCollection;
37#[cfg(feature = "event-service")]
38use crate::event_service::EventService;
39#[cfg(feature = "managers")]
40use crate::manager::ManagerCollection;
41#[cfg(feature = "oem-hpe")]
42use crate::oem::hpe::HpeiLoServiceExt;
43#[cfg(feature = "session-service")]
44use crate::session_service::SessionService;
45#[cfg(feature = "telemetry-service")]
46use crate::telemetry_service::TelemetryService;
47#[cfg(feature = "update-service")]
48use crate::update_service::UpdateService;
49
50pub type Vendor<T> = TaggedType<T, VendorTag>;
52#[doc(hidden)]
53#[derive(tagged_types::Tag)]
54#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
55#[transparent(Debug, Display, Serialize, Deserialize)]
56#[capability(inner_access, cloned)]
57pub enum VendorTag {}
58
59pub type Product<T> = TaggedType<T, ProductTag>;
61#[doc(hidden)]
62#[derive(tagged_types::Tag)]
63#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
64#[transparent(Debug, Display, Serialize, Deserialize)]
65#[capability(inner_access, cloned)]
66pub enum ProductTag {}
67
68pub type RedfishVersion<'a> = TaggedType<&'a str, RedfishVersionTag>;
70#[doc(hidden)]
71#[derive(tagged_types::Tag)]
72#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
73#[transparent(Debug, Display, Serialize, Deserialize)]
74#[capability(inner_access, cloned)]
75pub enum RedfishVersionTag {}
76
77#[derive(Clone)]
79pub struct ServiceRoot<B: Bmc> {
80 pub root: Arc<SchemaServiceRoot>,
82 #[allow(dead_code)] bmc: NvBmc<B>,
84}
85
86impl<B: Bmc> ServiceRoot<B> {
87 pub async fn new(bmc: Arc<B>) -> Result<Self, Error<B>> {
93 let root = NavProperty::<SchemaServiceRoot>::new_reference(ODataId::service_root())
94 .get(bmc.as_ref())
95 .await
96 .map_err(Error::Bmc)?;
97 let quirks = BmcQuirks::new(&root);
98 let mut protocol_features = root
99 .protocol_features_supported
100 .as_ref()
101 .map(ProtocolFeatures::new)
102 .unwrap_or_default();
103
104 if quirks.expand_is_not_working_properly() {
105 protocol_features.expand.expand_all = false;
106 protocol_features.expand.no_links = false;
107 }
108
109 let bmc = NvBmc::new(bmc, protocol_features, quirks);
110 Ok(Self { root, bmc })
111 }
112
113 #[must_use]
115 pub fn replace_bmc(self, bmc: Arc<B>) -> Self {
116 let root = self.root;
117 let bmc = self.bmc.replace_bmc(bmc);
118 Self { root, bmc }
119 }
120
121 #[must_use]
123 pub fn restrict_expand(self) -> Self {
124 let root = self.root;
125 let bmc = self.bmc.restrict_expand();
126 Self { root, bmc }
127 }
128
129 pub fn vendor(&self) -> Option<Vendor<&str>> {
131 self.root
132 .vendor
133 .as_ref()
134 .and_then(Option::as_ref)
135 .map(String::as_str)
136 .map(Vendor::new)
137 }
138
139 pub fn product(&self) -> Option<Product<&str>> {
141 self.root
142 .product
143 .as_ref()
144 .and_then(Option::as_ref)
145 .map(String::as_str)
146 .map(Product::new)
147 }
148
149 pub fn redfish_version(&self) -> Option<RedfishVersion<'_>> {
151 self.root
152 .redfish_version
153 .as_deref()
154 .map(RedfishVersion::new)
155 }
156
157 #[cfg(feature = "accounts")]
165 pub async fn account_service(&self) -> Result<Option<AccountService<B>>, Error<B>> {
166 AccountService::new(&self.bmc, self).await
167 }
168
169 #[cfg(feature = "chassis")]
177 pub async fn chassis(&self) -> Result<Option<ChassisCollection<B>>, Error<B>> {
178 ChassisCollection::new(&self.bmc, self).await
179 }
180
181 #[cfg(feature = "chassis")]
189 pub async fn chassis_links(&self) -> Result<Option<Vec<ChassisLink<B>>>, Error<B>> {
190 if let Some(collection) = &self.root.chassis {
191 let collection = collection
192 .get(self.bmc.as_ref())
193 .await
194 .map_err(Error::Bmc)?;
195 Ok(Some(
196 collection
197 .members
198 .iter()
199 .map(|member| {
200 ChassisLink::new(&self.bmc, NavProperty::new_reference(member.id().clone()))
201 })
202 .collect(),
203 ))
204 } else {
205 Ok(None)
206 }
207 }
208
209 #[cfg(feature = "computer-systems")]
217 pub async fn systems(&self) -> Result<Option<SystemCollection<B>>, Error<B>> {
218 SystemCollection::new(&self.bmc, self).await
219 }
220
221 #[cfg(feature = "update-service")]
229 pub async fn update_service(&self) -> Result<Option<UpdateService<B>>, Error<B>> {
230 UpdateService::new(&self.bmc, self).await
231 }
232
233 #[cfg(feature = "event-service")]
241 pub async fn event_service(&self) -> Result<Option<EventService<B>>, Error<B>> {
242 EventService::new(&self.bmc, self).await
243 }
244
245 #[cfg(feature = "telemetry-service")]
253 pub async fn telemetry_service(&self) -> Result<Option<TelemetryService<B>>, Error<B>> {
254 TelemetryService::new(&self.bmc, self).await
255 }
256
257 #[cfg(feature = "session-service")]
265 pub async fn session_service(&self) -> Result<Option<SessionService<B>>, Error<B>> {
266 SessionService::new(&self.bmc, self).await
267 }
268
269 #[cfg(feature = "managers")]
277 pub async fn managers(&self) -> Result<Option<ManagerCollection<B>>, Error<B>> {
278 ManagerCollection::new(&self.bmc, self).await
279 }
280
281 #[cfg(feature = "oem-hpe")]
289 pub fn oem_hpe_ilo_service_ext(&self) -> Result<Option<HpeiLoServiceExt<B>>, Error<B>> {
290 HpeiLoServiceExt::new(&self.root)
291 }
292}
293
294impl<B: Bmc> Resource for ServiceRoot<B> {
295 fn resource_ref(&self) -> &ResourceSchema {
296 &self.root.as_ref().base
297 }
298}