Skip to main content

nv_redfish/chassis/
network_adapter.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025 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
16//! Network adapters
17
18use crate::hardware_id::HardwareIdRef;
19use crate::hardware_id::Manufacturer as HardwareIdManufacturer;
20use crate::hardware_id::Model as HardwareIdModel;
21use crate::hardware_id::PartNumber as HardwareIdPartNumber;
22use crate::hardware_id::SerialNumber as HardwareIdSerialNumber;
23use crate::schema::network_adapter::NetworkAdapter as NetworkAdapterSchema;
24use crate::schema::network_adapter_collection::NetworkAdapterCollection as NetworkAdapterCollectionSchema;
25use crate::Error;
26use crate::NvBmc;
27use crate::Resource;
28use crate::ResourceSchema;
29use nv_redfish_core::Bmc;
30use nv_redfish_core::NavProperty;
31use std::sync::Arc;
32
33#[cfg(feature = "network-device-functions")]
34use crate::network_device_function::NetworkDeviceFunctionCollection;
35#[cfg(feature = "ports")]
36use crate::port::PortCollection;
37
38/// Network adapters collection.
39///
40/// Provides functions to access collection members.
41pub struct NetworkAdapterCollection<B: Bmc> {
42    bmc: NvBmc<B>,
43    collection: Arc<NetworkAdapterCollectionSchema>,
44}
45
46impl<B: Bmc> NetworkAdapterCollection<B> {
47    /// Create a new manager collection handle.
48    pub(crate) async fn new(
49        bmc: &NvBmc<B>,
50        nav: &NavProperty<NetworkAdapterCollectionSchema>,
51    ) -> Result<Self, Error<B>> {
52        let collection = bmc.expand_property(nav).await?;
53        Ok(Self {
54            bmc: bmc.clone(),
55            collection,
56        })
57    }
58
59    /// List all managers available in this BMC.
60    ///
61    /// # Errors
62    ///
63    /// Returns an error if fetching manager data fails.
64    pub async fn members(&self) -> Result<Vec<NetworkAdapter<B>>, Error<B>> {
65        let mut members = Vec::new();
66        for m in &self.collection.members {
67            members.push(NetworkAdapter::new(&self.bmc, m).await?);
68        }
69        Ok(members)
70    }
71}
72
73#[doc(hidden)]
74pub enum NetworkAdapterTag {}
75
76/// Network adapter manufacturer.
77pub type Manufacturer<T> = HardwareIdManufacturer<T, NetworkAdapterTag>;
78
79/// Network adapter model.
80pub type Model<T> = HardwareIdModel<T, NetworkAdapterTag>;
81
82/// Network adapter part number.
83pub type PartNumber<T> = HardwareIdPartNumber<T, NetworkAdapterTag>;
84
85/// Network adapter serial number.
86pub type SerialNumber<T> = HardwareIdSerialNumber<T, NetworkAdapterTag>;
87
88/// Network Adapter.
89///
90/// Provides functions to access log entries and perform log operations.
91pub struct NetworkAdapter<B: Bmc> {
92    #[allow(dead_code)] // used if any feature enabled.
93    bmc: NvBmc<B>,
94    data: Arc<NetworkAdapterSchema>,
95}
96
97impl<B: Bmc> NetworkAdapter<B> {
98    /// Create a new log service handle.
99    pub(crate) async fn new(
100        bmc: &NvBmc<B>,
101        nav: &NavProperty<NetworkAdapterSchema>,
102    ) -> Result<Self, Error<B>> {
103        nav.get(bmc.as_ref())
104            .await
105            .map_err(crate::Error::Bmc)
106            .map(|data| Self {
107                bmc: bmc.clone(),
108                data,
109            })
110    }
111
112    /// Get the raw schema data for this ethernet adapter.
113    #[must_use]
114    pub fn raw(&self) -> Arc<NetworkAdapterSchema> {
115        self.data.clone()
116    }
117
118    /// Get hardware identifier of the network adpater.
119    #[must_use]
120    pub fn hardware_id(&self) -> HardwareIdRef<'_, NetworkAdapterTag> {
121        HardwareIdRef {
122            manufacturer: self
123                .data
124                .manufacturer
125                .as_ref()
126                .and_then(Option::as_deref)
127                .map(Manufacturer::new),
128            model: self
129                .data
130                .model
131                .as_ref()
132                .and_then(Option::as_deref)
133                .map(Model::new),
134            part_number: self
135                .data
136                .part_number
137                .as_ref()
138                .and_then(Option::as_deref)
139                .map(PartNumber::new),
140            serial_number: self
141                .data
142                .serial_number
143                .as_ref()
144                .and_then(Option::as_deref)
145                .map(SerialNumber::new),
146        }
147    }
148
149    /// Get network device functions for this adapter.
150    ///
151    /// Returns `Ok(None)` when the network device functions link is absent.
152    ///
153    /// # Errors
154    ///
155    /// Returns an error if fetching network device functions data fails.
156    #[cfg(feature = "network-device-functions")]
157    pub async fn network_device_functions(
158        &self,
159    ) -> Result<Option<NetworkDeviceFunctionCollection<B>>, Error<B>> {
160        if let Some(p) = &self.data.network_device_functions {
161            NetworkDeviceFunctionCollection::new(&self.bmc, p)
162                .await
163                .map(Some)
164        } else {
165            Ok(None)
166        }
167    }
168
169    /// Get ports for this adapter.
170    ///
171    /// Returns `Ok(None)` when the ports link is absent.
172    ///
173    /// # Errors
174    ///
175    /// Returns an error if fetching the port collection fails.
176    #[cfg(feature = "ports")]
177    pub async fn ports(&self) -> Result<Option<PortCollection<B>>, Error<B>> {
178        if let Some(ports) = &self.data.ports {
179            PortCollection::new(&self.bmc, ports).await.map(Some)
180        } else {
181            Ok(None)
182        }
183    }
184}
185
186impl<B: Bmc> Resource for NetworkAdapter<B> {
187    fn resource_ref(&self) -> &ResourceSchema {
188        &self.data.as_ref().base
189    }
190}