Skip to main content

nv_redfish/manager/
item.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use crate::schema::manager::Manager as ManagerSchema;
17use crate::Error;
18use crate::NvBmc;
19use crate::Resource;
20use crate::ResourceSchema;
21use nv_redfish_core::Bmc;
22use nv_redfish_core::NavProperty;
23use std::sync::Arc;
24
25#[cfg(feature = "ethernet-interfaces")]
26use crate::ethernet_interface::EthernetInterfaceCollection;
27#[cfg(feature = "host-interfaces")]
28use crate::host_interface::HostInterfaceCollection;
29#[cfg(feature = "log-services")]
30use crate::log_service::LogService;
31#[cfg(feature = "oem-ami")]
32use crate::oem::ami::config_bmc::ConfigBmc as AmiConfigBmc;
33#[cfg(feature = "oem-dell-attributes")]
34use crate::oem::dell::attributes::DellAttributes;
35#[cfg(feature = "oem-hpe")]
36use crate::oem::hpe::manager::HpeManager;
37#[cfg(feature = "oem-lenovo")]
38use crate::oem::lenovo::manager::LenovoManager;
39#[cfg(feature = "oem-supermicro")]
40use crate::oem::supermicro::manager::SupermicroManager;
41
42/// Represents a manager (BMC) in the system.
43///
44/// Provides access to manager information and associated services.
45pub struct Manager<B: Bmc> {
46    #[allow(dead_code)] // enabled by features
47    bmc: NvBmc<B>,
48    data: Arc<ManagerSchema>,
49}
50
51impl<B: Bmc> Manager<B> {
52    /// Create a new manager handle.
53    pub(crate) async fn new(
54        bmc: &NvBmc<B>,
55        nav: &NavProperty<ManagerSchema>,
56    ) -> Result<Self, Error<B>> {
57        nav.get(bmc.as_ref())
58            .await
59            .map_err(Error::Bmc)
60            .map(|data| Self {
61                bmc: bmc.clone(),
62                data,
63            })
64    }
65
66    /// Get the raw schema data for this manager.
67    ///
68    /// Returns an `Arc` to the underlying schema, allowing cheap cloning
69    /// and sharing of the data.
70    #[must_use]
71    pub fn raw(&self) -> Arc<ManagerSchema> {
72        self.data.clone()
73    }
74
75    /// Get ethernet interfaces for this manager.
76    ///
77    /// Returns `Ok(None)` when the ethernet interfaces link is absent.
78    ///
79    /// # Errors
80    ///
81    /// Returns an error if fetching ethernet interfaces data fails.
82    #[cfg(feature = "ethernet-interfaces")]
83    pub async fn ethernet_interfaces(
84        &self,
85    ) -> Result<Option<EthernetInterfaceCollection<B>>, crate::Error<B>> {
86        if let Some(p) = &self.data.ethernet_interfaces {
87            EthernetInterfaceCollection::new(&self.bmc, p)
88                .await
89                .map(Some)
90        } else {
91            Ok(None)
92        }
93    }
94
95    /// Get host interfaces for this manager.
96    ///
97    /// Returns `Ok(None)` when the host interfaces link is absent.
98    ///
99    /// # Errors
100    ///
101    /// Returns an error if fetching host interfaces data fails.
102    #[cfg(feature = "host-interfaces")]
103    pub async fn host_interfaces(
104        &self,
105    ) -> Result<Option<HostInterfaceCollection<B>>, crate::Error<B>> {
106        if let Some(p) = &self.data.host_interfaces {
107            HostInterfaceCollection::new(&self.bmc, p).await.map(Some)
108        } else {
109            Ok(None)
110        }
111    }
112
113    /// Get log services for this manager.
114    ///
115    /// Returns `Ok(None)` when the log services link is absent.
116    ///
117    /// # Errors
118    ///
119    /// Returns an error if fetching log service data fails.
120    #[cfg(feature = "log-services")]
121    pub async fn log_services(&self) -> Result<Option<Vec<LogService<B>>>, crate::Error<B>> {
122        if let Some(log_services_ref) = &self.data.log_services {
123            let log_services_collection = log_services_ref
124                .get(self.bmc.as_ref())
125                .await
126                .map_err(crate::Error::Bmc)?;
127
128            let mut log_services = Vec::new();
129            for m in &log_services_collection.members {
130                log_services.push(LogService::new(&self.bmc, m).await?);
131            }
132
133            Ok(Some(log_services))
134        } else {
135            Ok(None)
136        }
137    }
138
139    /// Get Dell Manager attributes for this manager.
140    ///
141    /// Returns `Ok(None)` when the manager does not include `Oem.Dell`.
142    ///
143    /// # Errors
144    ///
145    /// Returns an error if fetching manager attributes data fails.
146    #[cfg(feature = "oem-dell-attributes")]
147    pub async fn oem_dell_attributes(&self) -> Result<Option<DellAttributes<B>>, Error<B>> {
148        DellAttributes::manager_attributes(&self.bmc, &self.data).await
149    }
150
151    /// Get Lenovo Manager OEM.
152    ///
153    /// Returns `Ok(None)` when the manager does not include `Oem.Lenovo`.
154    ///
155    /// # Errors
156    ///
157    /// Returns an error if parsing Lenovo manager OEM data fails.
158    #[cfg(feature = "oem-lenovo")]
159    pub fn oem_lenovo(&self) -> Result<Option<LenovoManager<B>>, Error<B>> {
160        LenovoManager::new(&self.bmc, &self.data)
161    }
162
163    /// Get HPE Manager OEM.
164    ///
165    /// Returns `Ok(None)` when the manager does not include `Oem.Hpe`.
166    ///
167    /// # Errors
168    ///
169    /// Returns an error if parsing HPE manager OEM data fails.
170    #[cfg(feature = "oem-hpe")]
171    pub fn oem_hpe(&self) -> Result<Option<HpeManager<B>>, Error<B>> {
172        HpeManager::new(&self.bmc, &self.data)
173    }
174
175    /// Get Supermicro Manager OEM.
176    ///
177    /// Returns `Ok(None)` when the manager does not include `Oem.Supermicro`.
178    ///
179    /// # Errors
180    ///
181    /// Returns an error if parsing Supermicro manager OEM data fails.
182    #[cfg(feature = "oem-supermicro")]
183    pub fn oem_supermicro(&self) -> Result<Option<SupermicroManager<B>>, Error<B>> {
184        SupermicroManager::new(&self.bmc, &self.data)
185    }
186
187    /// Get AMI Manager ConfigBMC OEM extension.
188    ///
189    /// Returns `Ok(None)` when the manager does not include `Oem.Ami` or `Oem.ConfigBMC`.
190    ///
191    /// # Errors
192    ///
193    /// Returns an error if retrieving BMC config data fails.
194    #[cfg(feature = "oem-ami")]
195    pub async fn oem_ami_config_bmc(&self) -> Result<Option<AmiConfigBmc<B>>, Error<B>> {
196        AmiConfigBmc::new(&self.bmc, &self.data).await
197    }
198}
199
200impl<B: Bmc> Resource for Manager<B> {
201    fn resource_ref(&self) -> &ResourceSchema {
202        &self.data.as_ref().base
203    }
204}