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