cx_sdk/client/
slos.rs

1// Copyright 2024 Coralogix Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::str::FromStr;
16
17use crate::error::{
18    SdkApiError,
19    SdkError,
20};
21use crate::{
22    auth::AuthContext,
23    error::Result,
24    metadata::CallProperties,
25    util::make_request_with_metadata,
26};
27
28use cx_api::proto::com::coralogixapis::apm::services::v1::{
29    BatchGetServiceSlosRequest,
30    BatchGetServiceSlosResponse,
31    CreateServiceSloRequest,
32    CreateServiceSloResponse,
33    DeleteServiceSloRequest,
34    DeleteServiceSloResponse,
35    GetServiceSloRequest,
36    GetServiceSloResponse,
37    ListServiceSlosRequest,
38    ListServiceSlosResponse,
39    ReplaceServiceSloRequest,
40    ReplaceServiceSloResponse,
41    service_slo_service_client::ServiceSloServiceClient,
42};
43
44pub use cx_api::proto::com::coralogixapis::apm::common::v2::OrderBy;
45pub use cx_api::proto::com::coralogixapis::apm::services::v1::{
46    CompareType,
47    ErrorSli,
48    ServiceSlo,
49    SliFilter,
50    SliMetricType,
51    SloPeriod,
52    SloStatus,
53    service_slo::SliType,
54};
55
56use tokio::sync::Mutex;
57use tonic::{
58    metadata::MetadataMap,
59    transport::{
60        Channel,
61        ClientTlsConfig,
62        Endpoint,
63    },
64};
65
66use crate::CoralogixRegion;
67
68const INFRA_MONITORING_FEATURE_GROUP_ID: &str = "infra-monitoring";
69
70/// The Service Line Objectives (SLO) client.
71/// Read more at <https://coralogix.com/docs/slo-management-api/>
72pub struct SloClient {
73    metadata_map: MetadataMap,
74    service_client: Mutex<ServiceSloServiceClient<Channel>>,
75}
76
77impl SloClient {
78    /// Creates a new client for the SLO.
79    ///
80    /// # Arguments
81    /// * `auth_context` - The [`AuthContext`] to use for authentication.
82    /// * `region` - The [`CoralogixRegion`] to connect to.
83    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
84        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
85            .tls_config(ClientTlsConfig::new().with_native_roots())?
86            .connect_lazy();
87        let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
88        Ok(Self {
89            metadata_map: request_metadata.to_metadata_map(),
90            service_client: Mutex::new(ServiceSloServiceClient::new(channel)),
91        })
92    }
93
94    /// Creates a new Service SLO.
95    ///
96    /// # Arguments
97    /// * `slo` - The [`ServiceSlo`] to create.
98    pub async fn create(&self, slo: ServiceSlo) -> Result<CreateServiceSloResponse> {
99        let request = make_request_with_metadata(
100            CreateServiceSloRequest { slo: Some(slo) },
101            &self.metadata_map,
102        );
103        self.service_client
104            .lock()
105            .await
106            .create_service_slo(request)
107            .await
108            .map(|r| r.into_inner())
109            .map_err(|status| {
110                SdkError::ApiError(SdkApiError {
111                    status,
112                    endpoint:
113                        "/com.coralogixapis.apm.services.v1.ServiceSloService/CreateServiceSlo"
114                            .to_string(),
115                    feature_group: INFRA_MONITORING_FEATURE_GROUP_ID.to_string(),
116                })
117            })
118    }
119
120    /// Updates an existing SLO.
121    ///
122    /// # Arguments
123    /// * `slo` - The [`ServiceSlo`] to update.    
124    pub async fn update(&self, slo: ServiceSlo) -> Result<ReplaceServiceSloResponse> {
125        let request = make_request_with_metadata(
126            ReplaceServiceSloRequest { slo: Some(slo) },
127            &self.metadata_map,
128        );
129        self.service_client
130            .lock()
131            .await
132            .replace_service_slo(request)
133            .await
134            .map(|r| r.into_inner())
135            .map_err(|status| {
136                SdkError::ApiError(SdkApiError {
137                    status,
138                    endpoint:
139                        "/com.coralogixapis.apm.services.v1.ServiceSloService/ReplaceServiceSlo"
140                            .to_string(),
141                    feature_group: INFRA_MONITORING_FEATURE_GROUP_ID.to_string(),
142                })
143            })
144    }
145
146    /// Deletes a Service SLO.
147    ///
148    /// # Arguments
149    /// * `id` - The id of the Service SLO to delete.
150    pub async fn delete(&self, id: String) -> Result<DeleteServiceSloResponse> {
151        let request = make_request_with_metadata(
152            DeleteServiceSloRequest { id: Some(id) },
153            &self.metadata_map,
154        );
155        self.service_client
156            .lock()
157            .await
158            .delete_service_slo(request)
159            .await
160            .map(|r| r.into_inner())
161            .map_err(|status| {
162                SdkError::ApiError(SdkApiError {
163                    status,
164                    endpoint:
165                        "/com.coralogixapis.apm.services.v1.ServiceSloService/DeleteServiceSlo"
166                            .to_string(),
167                    feature_group: INFRA_MONITORING_FEATURE_GROUP_ID.to_string(),
168                })
169            })
170    }
171
172    /// Get the Service SLO.
173    ///
174    /// # Arguments
175    /// * `id` - The ID of the Service SLO
176    pub async fn get(&self, id: String) -> Result<GetServiceSloResponse> {
177        let request =
178            make_request_with_metadata(GetServiceSloRequest { id: Some(id) }, &self.metadata_map);
179
180        self.service_client
181            .lock()
182            .await
183            .get_service_slo(request)
184            .await
185            .map(|r| r.into_inner())
186            .map_err(|status| {
187                SdkError::ApiError(SdkApiError {
188                    status,
189                    endpoint: "/com.coralogixapis.apm.services.v1.ServiceSloService/GetServiceSlo"
190                        .to_string(),
191                    feature_group: INFRA_MONITORING_FEATURE_GROUP_ID.to_string(),
192                })
193            })
194    }
195
196    /// Get the Service SLO in bulk.
197    ///
198    /// # Arguments
199    /// * `ids` - The IDs of the Service SLO
200    pub async fn get_bulk(&self, ids: Vec<String>) -> Result<BatchGetServiceSlosResponse> {
201        let request =
202            make_request_with_metadata(BatchGetServiceSlosRequest { ids }, &self.metadata_map);
203
204        self.service_client
205            .lock()
206            .await
207            .batch_get_service_slos(request)
208            .await
209            .map(|r| r.into_inner())
210            .map_err(|status| {
211                SdkError::ApiError(SdkApiError {
212                    status,
213                    endpoint:
214                        "/com.coralogixapis.apm.services.v1.ServiceSloService/BatchGetServiceSlos"
215                            .to_string(),
216                    feature_group: INFRA_MONITORING_FEATURE_GROUP_ID.to_string(),
217                })
218            })
219    }
220
221    /// List the Service SLOs.
222    ///
223    /// # Arguments
224    /// * `service_names` - The names of the services to list SLOs for.
225    /// * `order_by` - Ordering of the SLOs.
226    pub async fn list(
227        &self,
228        service_names: Vec<String>,
229        order_by: Option<OrderBy>,
230    ) -> Result<ListServiceSlosResponse> {
231        let request = make_request_with_metadata(
232            ListServiceSlosRequest {
233                order_by,
234                service_names,
235            },
236            &self.metadata_map,
237        );
238
239        self.service_client
240            .lock()
241            .await
242            .list_service_slos(request)
243            .await
244            .map(|r| r.into_inner())
245            .map_err(|status| {
246                SdkError::ApiError(SdkApiError {
247                    status,
248                    endpoint:
249                        "/com.coralogixapis.apm.services.v1.ServiceSloService/ListServiceSlos"
250                            .to_string(),
251                    feature_group: INFRA_MONITORING_FEATURE_GROUP_ID.to_string(),
252                })
253            })
254    }
255}