nv_redfish/
service_root.rs1use crate::bmc_quirks::BmcQuirks;
17use crate::core::Bmc;
18use crate::core::NavProperty;
19use crate::core::ODataId;
20use crate::schema::redfish::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 = "computer-systems")]
34use crate::computer_system::SystemCollection;
35#[cfg(feature = "event-service")]
36use crate::event_service::EventService;
37#[cfg(feature = "managers")]
38use crate::manager::ManagerCollection;
39#[cfg(feature = "oem-hpe")]
40use crate::oem::hpe::HpeiLoServiceExt;
41#[cfg(feature = "telemetry-service")]
42use crate::telemetry_service::TelemetryService;
43#[cfg(feature = "update-service")]
44use crate::update_service::UpdateService;
45#[cfg(feature = "session-service")]
46use crate::session_service::SessionService;
47
48pub type Vendor<T> = TaggedType<T, VendorTag>;
50#[doc(hidden)]
51#[derive(tagged_types::Tag)]
52#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
53#[transparent(Debug, Display, Serialize, Deserialize)]
54#[capability(inner_access, cloned)]
55pub enum VendorTag {}
56
57pub type Product<T> = TaggedType<T, ProductTag>;
59#[doc(hidden)]
60#[derive(tagged_types::Tag)]
61#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
62#[transparent(Debug, Display, Serialize, Deserialize)]
63#[capability(inner_access, cloned)]
64pub enum ProductTag {}
65
66pub type RedfishVersion<'a> = TaggedType<&'a str, RedfishVersionTag>;
68#[doc(hidden)]
69#[derive(tagged_types::Tag)]
70#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
71#[transparent(Debug, Display, Serialize, Deserialize)]
72#[capability(inner_access, cloned)]
73pub enum RedfishVersionTag {}
74
75#[derive(Clone)]
77pub struct ServiceRoot<B: Bmc> {
78 pub root: Arc<SchemaServiceRoot>,
80 #[allow(dead_code)] bmc: NvBmc<B>,
82}
83
84impl<B: Bmc> ServiceRoot<B> {
85 pub async fn new(bmc: Arc<B>) -> Result<Self, Error<B>> {
91 let root = NavProperty::<SchemaServiceRoot>::new_reference(ODataId::service_root())
92 .get(bmc.as_ref())
93 .await
94 .map_err(Error::Bmc)?;
95 let quirks = BmcQuirks::new(&root);
96 let mut protocol_features = root
97 .protocol_features_supported
98 .as_ref()
99 .map(ProtocolFeatures::new)
100 .unwrap_or_default();
101
102 if quirks.expand_is_not_working_properly() {
103 protocol_features.expand.expand_all = false;
104 protocol_features.expand.no_links = false;
105 }
106
107 let bmc = NvBmc::new(bmc, protocol_features, quirks);
108 Ok(Self { root, bmc })
109 }
110
111 #[must_use]
113 pub fn replace_bmc(self, bmc: Arc<B>) -> Self {
114 let root = self.root;
115 let bmc = self.bmc.replace_bmc(bmc);
116 Self { root, bmc }
117 }
118
119 #[must_use]
121 pub fn restrict_expand(self) -> Self {
122 let root = self.root;
123 let bmc = self.bmc.restrict_expand();
124 Self { root, bmc }
125 }
126
127 pub fn vendor(&self) -> Option<Vendor<&str>> {
129 self.root
130 .vendor
131 .as_ref()
132 .and_then(Option::as_ref)
133 .map(String::as_str)
134 .map(Vendor::new)
135 }
136
137 pub fn product(&self) -> Option<Product<&str>> {
139 self.root
140 .product
141 .as_ref()
142 .and_then(Option::as_ref)
143 .map(String::as_str)
144 .map(Product::new)
145 }
146
147 pub fn redfish_version(&self) -> Option<RedfishVersion<'_>> {
149 self.root
150 .redfish_version
151 .as_deref()
152 .map(RedfishVersion::new)
153 }
154
155 #[cfg(feature = "accounts")]
163 pub async fn account_service(&self) -> Result<Option<AccountService<B>>, Error<B>> {
164 AccountService::new(&self.bmc, self).await
165 }
166
167 #[cfg(feature = "chassis")]
175 pub async fn chassis(&self) -> Result<Option<ChassisCollection<B>>, Error<B>> {
176 ChassisCollection::new(&self.bmc, self).await
177 }
178
179 #[cfg(feature = "computer-systems")]
187 pub async fn systems(&self) -> Result<Option<SystemCollection<B>>, Error<B>> {
188 SystemCollection::new(&self.bmc, self).await
189 }
190
191 #[cfg(feature = "update-service")]
199 pub async fn update_service(&self) -> Result<Option<UpdateService<B>>, Error<B>> {
200 UpdateService::new(&self.bmc, self).await
201 }
202
203 #[cfg(feature = "event-service")]
211 pub async fn event_service(&self) -> Result<Option<EventService<B>>, Error<B>> {
212 EventService::new(&self.bmc, self).await
213 }
214
215 #[cfg(feature = "telemetry-service")]
223 pub async fn telemetry_service(&self) -> Result<Option<TelemetryService<B>>, Error<B>> {
224 TelemetryService::new(&self.bmc, self).await
225 }
226
227 #[cfg(feature = "session-service")]
235 pub async fn session_service(&self) -> Result<Option<SessionService<B>>, Error<B>> {
236 SessionService::new(&self.bmc, self).await
237 }
238
239 #[cfg(feature = "managers")]
247 pub async fn managers(&self) -> Result<Option<ManagerCollection<B>>, Error<B>> {
248 ManagerCollection::new(&self.bmc, self).await
249 }
250
251 #[cfg(feature = "oem-hpe")]
259 pub fn oem_hpe_ilo_service_ext(&self) -> Result<Option<HpeiLoServiceExt<B>>, Error<B>> {
260 HpeiLoServiceExt::new(&self.root)
261 }
262}
263
264impl<B: Bmc> Resource for ServiceRoot<B> {
265 fn resource_ref(&self) -> &ResourceSchema {
266 &self.root.as_ref().base
267 }
268}