cx_sdk/client/
dashboards.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::{
18    auth::AuthContext,
19    error::{
20        Result,
21        SdkApiError,
22        SdkError,
23    },
24    metadata::CallProperties,
25    util::make_request_with_metadata,
26};
27
28pub use crate::com::coralogixapis::actions::v2::Action;
29
30pub use cx_api::proto::com::coralogixapis::dashboards::v1::ast::*;
31use cx_api::proto::com::coralogixapis::dashboards::v1::services::{
32    AssignDashboardFolderRequest,
33    AssignDashboardFolderResponse,
34    CreateDashboardRequest,
35    CreateDashboardResponse,
36    DeleteDashboardRequest,
37    DeleteDashboardResponse,
38    GetDashboardCatalogRequest,
39    GetDashboardCatalogResponse,
40    GetDashboardRequest,
41    GetDashboardResponse,
42    PinDashboardRequest,
43    PinDashboardResponse,
44    ReplaceDashboardRequest,
45    ReplaceDashboardResponse,
46    UnpinDashboardRequest,
47    UnpinDashboardResponse,
48    dashboard_catalog_service_client::DashboardCatalogServiceClient,
49    dashboards_service_client::DashboardsServiceClient,
50};
51use tokio::sync::Mutex;
52use tonic::{
53    Request,
54    metadata::MetadataMap,
55    transport::{
56        Channel,
57        ClientTlsConfig,
58        Endpoint,
59    },
60};
61
62const DASHBOARDS_FEATURE_GROUP_ID: &str = "dashboards";
63
64use crate::CoralogixRegion;
65
66/// The Dashboards API client.
67/// Read more at <https://coralogix.com/docs/custom-dashboards/>
68pub struct DashboardsClient {
69    teams_level_metadata_map: MetadataMap,
70    user_level_metadata_map: MetadataMap,
71    service_client: Mutex<DashboardsServiceClient<Channel>>,
72    catalog_client: Mutex<DashboardCatalogServiceClient<Channel>>,
73}
74
75impl DashboardsClient {
76    /// Creates a new client for the Dashboards API.
77    ///
78    /// # Arguments
79    /// * `auth_context` - The [`AuthContext`] to use for authentication.
80    /// * `region` - The [`CoralogixRegion`] to connect to.
81    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
82        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
83            .tls_config(ClientTlsConfig::new().with_native_roots())?
84            .connect_lazy();
85        let teams_level_auth_data: CallProperties = (&auth_context.team_level_api_key).into();
86        let user_level_auth_data: CallProperties = (&auth_context.user_level_api_key).into();
87        Ok(Self {
88            teams_level_metadata_map: teams_level_auth_data.to_metadata_map(),
89            user_level_metadata_map: user_level_auth_data.to_metadata_map(),
90            service_client: Mutex::new(DashboardsServiceClient::new(channel.clone())),
91            catalog_client: Mutex::new(DashboardCatalogServiceClient::new(channel)),
92        })
93    }
94
95    /// Creates a new dashboard.
96    ///
97    /// # Arguments
98    /// * `dashboard` - The dashboard to create.
99    pub async fn create(
100        &self,
101        dashboard: Dashboard,
102        is_locked: bool,
103    ) -> Result<CreateDashboardResponse> {
104        let request: Request<CreateDashboardRequest> = make_request_with_metadata(
105            CreateDashboardRequest {
106                request_id: None,
107                dashboard: Some(dashboard),
108                is_locked: Some(is_locked),
109            },
110            &self.teams_level_metadata_map,
111        );
112        {
113            let mut client = self.service_client.lock().await.clone();
114
115            client
116                .create_dashboard(request)
117                .await
118                .map(|r| r.into_inner())
119                .map_err(|status| {
120                    SdkError::ApiError(SdkApiError {
121                        status,
122                        endpoint:
123                            "/com.coralogixapis.dashboards.v1.DashboardsService/CreateDashboard"
124                                .into(),
125                        feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
126                    })
127                })
128        }
129    }
130
131    /// Replaces a dashboard.
132    ///
133    /// # Arguments
134    /// * `dashboard` - The [`Dashboard`] to replace.
135    pub async fn replace(
136        &self,
137        dashboard: Dashboard,
138        is_locked: bool,
139    ) -> Result<ReplaceDashboardResponse> {
140        let request: Request<ReplaceDashboardRequest> = make_request_with_metadata(
141            ReplaceDashboardRequest {
142                request_id: None,
143                dashboard: Some(dashboard),
144                is_locked: Some(is_locked),
145            },
146            &self.teams_level_metadata_map,
147        );
148        {
149            let mut client = self.service_client.lock().await.clone();
150
151            client
152                .replace_dashboard(request)
153                .await
154                .map(|r| r.into_inner())
155                .map_err(|status| {
156                    SdkError::ApiError(SdkApiError {
157                        status,
158                        endpoint:
159                            "/com.coralogixapis.dashboards.v1.DashboardsService/ReplaceDashboard"
160                                .into(),
161                        feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
162                    })
163                })
164        }
165    }
166
167    /// Gets a dashboard by its ID.
168    ///
169    /// # Arguments
170    /// * `dashboard_id` - The ID of the dashboard to get.
171    pub async fn get(&self, dashboard_id: String) -> Result<GetDashboardResponse> {
172        let request: Request<GetDashboardRequest> = make_request_with_metadata(
173            GetDashboardRequest {
174                dashboard_id: Some(dashboard_id),
175            },
176            &self.teams_level_metadata_map,
177        );
178        {
179            let mut client = self.service_client.lock().await.clone();
180
181            client
182                .get_dashboard(request)
183                .await
184                .map(|r| r.into_inner())
185                .map_err(|status| {
186                    SdkError::ApiError(SdkApiError {
187                        status,
188                        endpoint: "/com.coralogixapis.dashboards.v1.DashboardsService/GetDashboard"
189                            .into(),
190                        feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
191                    })
192                })
193        }
194    }
195
196    /// Lists all dashboards.
197    pub async fn list(&self) -> Result<GetDashboardCatalogResponse> {
198        let mut client = self.catalog_client.lock().await.clone();
199
200        client
201            .get_dashboard_catalog(make_request_with_metadata(
202                GetDashboardCatalogRequest {},
203                &self.user_level_metadata_map,
204            ))
205            .await
206            .map(|r| r.into_inner())
207            .map_err(
208                |status| SdkError::ApiError(SdkApiError {
209                    status,
210                    endpoint: "/com.coralogixapis.dashboards.v1.DashboardCatalogService/GetDashboardCatalog".into(),
211                    feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
212                },
213            ))
214    }
215
216    /// Deletes a dashboard by its ID.
217    ///
218    /// # Arguments
219    /// * `dashboard_id` - The ID of the dashboard to delete.
220    pub async fn delete(&self, dashboard_id: String) -> Result<DeleteDashboardResponse> {
221        let request: Request<DeleteDashboardRequest> = make_request_with_metadata(
222            DeleteDashboardRequest {
223                request_id: None,
224                dashboard_id: Some(dashboard_id),
225            },
226            &self.teams_level_metadata_map,
227        );
228        {
229            let mut client = self.service_client.lock().await.clone();
230
231            client
232                .delete_dashboard(request)
233                .await
234                .map(|r| r.into_inner())
235                .map_err(|status| {
236                    SdkError::ApiError(SdkApiError {
237                        status,
238                        endpoint:
239                            "/com.coralogixapis.dashboards.v1.DashboardsService/DeleteDashboard"
240                                .into(),
241                        feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
242                    })
243                })
244        }
245    }
246
247    /// Pins a dashboard by its ID.
248    ///
249    /// # Arguments
250    /// * `dashboard_id` - The ID of the dashboard to pin.
251    pub async fn pin(&self, dashboard_id: String) -> Result<PinDashboardResponse> {
252        let request: Request<PinDashboardRequest> = make_request_with_metadata(
253            PinDashboardRequest {
254                request_id: None,
255                dashboard_id: Some(dashboard_id),
256            },
257            &self.user_level_metadata_map,
258        );
259        {
260            let mut client = self.service_client.lock().await.clone();
261
262            client
263                .pin_dashboard(request)
264                .await
265                .map(|r| r.into_inner())
266                .map_err(|status| {
267                    SdkError::ApiError(SdkApiError {
268                        status,
269                        endpoint: "/com.coralogixapis.dashboards.v1.DashboardsService/PinDashboard"
270                            .into(),
271                        feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
272                    })
273                })
274        }
275    }
276
277    /// Unpins a dashboard by its ID.
278    ///
279    /// # Arguments
280    /// * `dashboard_id` - The ID of the dashboard to unpin.
281    pub async fn unpin(&self, dashboard_id: String) -> Result<UnpinDashboardResponse> {
282        let request: Request<UnpinDashboardRequest> = make_request_with_metadata(
283            UnpinDashboardRequest {
284                request_id: None,
285                dashboard_id: Some(dashboard_id),
286            },
287            &self.user_level_metadata_map,
288        );
289        {
290            let mut client = self.service_client.lock().await.clone();
291
292            client
293                .unpin_dashboard(request)
294                .await
295                .map(|r| r.into_inner())
296                .map_err(|status| {
297                    SdkError::ApiError(SdkApiError {
298                        status,
299                        endpoint:
300                            "/com.coralogixapis.dashboards.v1.DashboardsService/UnpinDashboard"
301                                .into(),
302                        feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
303                    })
304                })
305        }
306    }
307
308    /// Assigns a dashboard to a folder.
309    ///
310    /// # Arguments
311    /// * `dashboard_id` - The ID of the dashboard to assign.
312    /// * `folder_id` - The ID of the folder to assign the dashboard to.
313    pub async fn assign_to_folder(
314        &self,
315        dashboard_id: String,
316        folder_id: String,
317    ) -> Result<AssignDashboardFolderResponse> {
318        let request: Request<AssignDashboardFolderRequest> = make_request_with_metadata(
319            AssignDashboardFolderRequest {
320                request_id: None,
321                dashboard_id: Some(dashboard_id),
322                folder_id: Some(folder_id),
323            },
324            &self.teams_level_metadata_map,
325        );
326        {
327            let mut client = self.service_client.lock().await.clone();
328
329            client
330                .assign_dashboard_folder(request)
331                .await
332                .map(|r| r.into_inner())
333                .map_err(
334                    |status| SdkError::ApiError(SdkApiError {
335                        status,
336                        endpoint: "/com.coralogixapis.dashboards.v1.DashboardsService/AssignDashboardFolder".into(),
337                        feature_group: DASHBOARDS_FEATURE_GROUP_ID.into(),
338                    },
339                ))
340        }
341    }
342}