Skip to main content

nv_redfish/telemetry_service/
mod.rs

1// SPDX-FileCopyrightText: Copyright (c) 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
16//! Telemetry Service entities and helpers.
17//!
18//! This module provides typed access to Redfish `TelemetryService`.
19
20mod metric_definition;
21mod metric_report;
22mod metric_report_definition;
23
24use crate::schema::redfish::telemetry_service::TelemetryService as TelemetryServiceSchema;
25use crate::schema::redfish::telemetry_service::TelemetryServiceUpdate;
26use crate::Error;
27use crate::NvBmc;
28use crate::Resource;
29use crate::ResourceSchema;
30use crate::ServiceRoot;
31use nv_redfish_core::Bmc;
32use nv_redfish_core::Empty;
33use nv_redfish_core::EntityTypeRef as _;
34use nv_redfish_core::NavProperty;
35use std::sync::Arc;
36
37#[doc(inline)]
38pub use metric_definition::MetricDefinition;
39#[doc(inline)]
40pub use metric_definition::MetricDefinitionCreate;
41#[doc(inline)]
42pub use metric_definition::MetricDefinitionUpdate;
43#[doc(inline)]
44pub use metric_report::MetricReportRef;
45#[doc(inline)]
46pub use metric_report_definition::MetricReportDefinition;
47#[doc(inline)]
48pub use metric_report_definition::MetricReportDefinitionCreate;
49#[doc(inline)]
50pub use metric_report_definition::MetricReportDefinitionType;
51#[doc(inline)]
52pub use metric_report_definition::MetricReportDefinitionUpdate;
53#[doc(inline)]
54pub use metric_report_definition::ReportActionsEnum;
55#[doc(inline)]
56pub use metric_report_definition::Wildcard;
57#[doc(inline)]
58pub use metric_report_definition::WildcardUpdate;
59
60/// Telemetry service.
61///
62/// Provides access to metric reports and metric definitions.
63pub struct TelemetryService<B: Bmc> {
64    data: Arc<TelemetryServiceSchema>,
65    bmc: NvBmc<B>,
66}
67
68impl<B: Bmc> TelemetryService<B> {
69    /// Create a new telemetry service handle.
70    pub(crate) async fn new(
71        bmc: &NvBmc<B>,
72        root: &ServiceRoot<B>,
73    ) -> Result<Option<Self>, Error<B>> {
74        if let Some(service_ref) = &root.root.telemetry_service {
75            let data = service_ref.get(bmc.as_ref()).await.map_err(Error::Bmc)?;
76            Ok(Some(Self {
77                data,
78                bmc: bmc.clone(),
79            }))
80        } else {
81            Ok(None)
82        }
83    }
84
85    /// Get the raw schema data for this telemetry service.
86    #[must_use]
87    pub fn raw(&self) -> Arc<TelemetryServiceSchema> {
88        self.data.clone()
89    }
90
91    /// Enable or disable telemetry service.
92    ///
93    /// # Errors
94    ///
95    /// Returns an error if updating telemetry service fails.
96    pub async fn set_enabled(&self, enabled: bool) -> Result<Self, Error<B>> {
97        let update = TelemetryServiceUpdate::builder()
98            .with_service_enabled(enabled)
99            .build();
100
101        let updated = self
102            .bmc
103            .as_ref()
104            .update(self.data.odata_id(), self.data.etag(), &update)
105            .await
106            .map_err(Error::Bmc)?;
107
108        Ok(Self {
109            data: Arc::new(updated),
110            bmc: self.bmc.clone(),
111        })
112    }
113
114    /// Get `Vec<MetricReportRef>` associated with this telemetry service.
115    ///
116    /// Fetches the metric report collection and returns a list of
117    /// [`MetricReportRef`] handles.
118    ///
119    /// # Errors
120    ///
121    /// Returns an error if:
122    /// - the telemetry service does not expose a `MetricReports` collection
123    /// - retrieving the collection fails
124    pub async fn metric_reports(&self) -> Result<Option<Vec<MetricReportRef<B>>>, Error<B>> {
125        if let Some(collection_ref) = &self.data.metric_reports {
126            let collection = collection_ref
127                .get(self.bmc.as_ref())
128                .await
129                .map_err(Error::Bmc)?;
130
131            let mut items = Vec::with_capacity(collection.members.len());
132            for m in &collection.members {
133                items.push(MetricReportRef::new(
134                    &self.bmc,
135                    NavProperty::new_reference(m.id().clone()),
136                ));
137            }
138
139            Ok(Some(items))
140        } else {
141            Ok(None)
142        }
143    }
144
145    /// Get `Vec<MetricDefinition>` associated with this telemetry service.
146    ///
147    /// Fetches the metric definition collection and returns a list of [`MetricDefinition`] handles.
148    ///
149    /// # Errors
150    ///
151    /// Returns an error if:
152    /// - the telemetry service does not expose a `MetricDefinitions` collection
153    /// - retrieving the collection fails
154    pub async fn metric_definitions(&self) -> Result<Option<Vec<MetricDefinition<B>>>, Error<B>> {
155        if let Some(collection_ref) = &self.data.metric_definitions {
156            let collection = collection_ref
157                .get(self.bmc.as_ref())
158                .await
159                .map_err(Error::Bmc)?;
160
161            let mut items = Vec::with_capacity(collection.members.len());
162            for m in &collection.members {
163                items.push(MetricDefinition::new(&self.bmc, m).await?);
164            }
165
166            Ok(Some(items))
167        } else {
168            Ok(None)
169        }
170    }
171
172    /// Get `Vec<MetricReportDefinition>` associated with this telemetry service.
173    ///
174    /// Fetches the metric report definition collection and returns a list of
175    /// [`MetricReportDefinition`] handles.
176    ///
177    /// # Errors
178    ///
179    /// Returns an error if:
180    /// - the telemetry service does not expose a `MetricReportDefinitions` collection
181    /// - retrieving the collection fails
182    pub async fn metric_report_definitions(
183        &self,
184    ) -> Result<Option<Vec<MetricReportDefinition<B>>>, Error<B>> {
185        if let Some(collection_ref) = &self.data.metric_report_definitions {
186            let collection = collection_ref
187                .get(self.bmc.as_ref())
188                .await
189                .map_err(Error::Bmc)?;
190
191            let mut items = Vec::with_capacity(collection.members.len());
192            for m in &collection.members {
193                items.push(MetricReportDefinition::new(&self.bmc, m).await?);
194            }
195
196            Ok(Some(items))
197        } else {
198            Ok(None)
199        }
200    }
201
202    /// Create a metric definition.
203    ///
204    /// # Errors
205    ///
206    /// Returns an error if:
207    /// - the telemetry service does not expose a `MetricDefinitions` collection
208    /// - creating the entity fails
209    pub async fn create_metric_definition(
210        &self,
211        create: &MetricDefinitionCreate,
212    ) -> Result<Empty, Error<B>> {
213        let collection_ref = self
214            .data
215            .metric_definitions
216            .as_ref()
217            .ok_or(Error::MetricDefinitionsNotAvailable)?;
218
219        self.bmc
220            .as_ref()
221            .create(collection_ref.id(), create)
222            .await
223            .map_err(Error::Bmc)
224    }
225
226    /// Create a metric report definition.
227    ///
228    /// # Errors
229    ///
230    /// Returns an error if:
231    /// - the telemetry service does not expose a `MetricReportDefinitions` collection
232    /// - creating the entity fails
233    pub async fn create_metric_report_definition(
234        &self,
235        create: &MetricReportDefinitionCreate,
236    ) -> Result<Empty, Error<B>> {
237        let collection_ref = self
238            .data
239            .metric_report_definitions
240            .as_ref()
241            .ok_or(Error::MetricReportDefinitionsNotAvailable)?;
242
243        self.bmc
244            .as_ref()
245            .create(collection_ref.id(), create)
246            .await
247            .map_err(Error::Bmc)
248    }
249}
250
251impl<B: Bmc> Resource for TelemetryService<B> {
252    fn resource_ref(&self) -> &ResourceSchema {
253        &self.data.as_ref().base
254    }
255}