cx_sdk/client/
teams.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
28use cx_api::proto::com::coralogixapis::aaa::organisations::v2::{
29    CreateTeamInOrgRequest,
30    CreateTeamInOrgResponse,
31    DeleteTeamRequest,
32    DeleteTeamResponse,
33    GetTeamQuotaRequest,
34    GetTeamQuotaResponse,
35    GetTeamRequest,
36    GetTeamResponse,
37    ListTeamsRequest,
38    ListTeamsResponse,
39    MoveQuotaRequest,
40    MoveQuotaResponse,
41    SetDailyQuotaRequest,
42    SetDailyQuotaResponse,
43    TeamId,
44    UpdateTeamRequest,
45    UpdateTeamResponse,
46    team_service_client::TeamServiceClient,
47};
48use tokio::sync::Mutex;
49use tonic::{
50    metadata::MetadataMap,
51    transport::{
52        Channel,
53        ClientTlsConfig,
54        Endpoint,
55    },
56};
57
58use crate::CoralogixRegion;
59
60const TEAMS_FEATURE_GROUP_ID: &str = "aaa";
61
62/// The Team API client.
63/// Read more at https://coralogix.com/docs/user-team-management/ and https://coralogix.com/docs/user-guides/account-management/payment-and-billing/quota-management/
64pub struct TeamsClient {
65    metadata_map: MetadataMap,
66    service_client: Mutex<TeamServiceClient<Channel>>,
67}
68
69impl TeamsClient {
70    /// Creates a new client for the Teams API.
71    ///
72    /// # Arguments
73    /// * `auth_context` - The [`AuthContext`] to use for authentication.
74    /// * `region` - The [`CoralogixRegion`] to connect to.
75    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
76        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
77            .tls_config(ClientTlsConfig::new().with_native_roots())?
78            .connect_lazy();
79        let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
80        Ok(Self {
81            metadata_map: request_metadata.to_metadata_map(),
82            service_client: Mutex::new(TeamServiceClient::new(channel)),
83        })
84    }
85
86    /// Creates a new Team in the organization.
87    ///
88    /// # Arguments
89    /// * `team_name` - The name of the team.
90    /// * `team_admins_email` - The email addresses of the team admins.
91    /// * `daily_quota` - The daily quota for the team.
92    pub async fn create(
93        &self,
94        team_name: String,
95        team_admins_email: Vec<String>,
96        daily_quota: Option<f64>,
97    ) -> Result<CreateTeamInOrgResponse> {
98        let request = make_request_with_metadata(
99            CreateTeamInOrgRequest {
100                team_name,
101                team_admins_email,
102                daily_quota,
103            },
104            &self.metadata_map,
105        );
106        self.service_client
107            .lock()
108            .await
109            .create_team_in_org(request)
110            .await
111            .map(|r| r.into_inner())
112            .map_err(|status| {
113                SdkError::ApiError(SdkApiError {
114                    status,
115                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/CreateTeamInOrg"
116                        .to_string(),
117                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
118                })
119            })
120    }
121
122    /// Update the Team identified by its id.
123    ///
124    /// # Arguments
125    /// * `team_id` - The id of the team to replace.
126    /// * `team_name` - The name of the team.
127    /// * `daily_quota` - The daily quota for the team.
128    pub async fn replace(
129        &self,
130        team_id: u32,
131        team_name: Option<String>,
132        daily_quota: Option<f64>,
133    ) -> Result<UpdateTeamResponse> {
134        let request = make_request_with_metadata(
135            UpdateTeamRequest {
136                team_id: Some(TeamId { id: team_id }),
137                team_name,
138                daily_quota,
139            },
140            &self.metadata_map,
141        );
142        self.service_client
143            .lock()
144            .await
145            .update_team(request)
146            .await
147            .map(|r| r.into_inner())
148            .map_err(|status| {
149                SdkError::ApiError(SdkApiError {
150                    status,
151                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/UpdateTeam"
152                        .to_string(),
153                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
154                })
155            })
156    }
157
158    /// Deletes the Team identified by its id.
159    ///
160    /// # Arguments
161    /// * `team_id` - The id of the team to delete.
162    pub async fn delete(&self, team_id: u32) -> Result<DeleteTeamResponse> {
163        let request = make_request_with_metadata(
164            DeleteTeamRequest {
165                team_id: Some(TeamId { id: team_id }),
166            },
167            &self.metadata_map,
168        );
169        self.service_client
170            .lock()
171            .await
172            .delete_team(request)
173            .await
174            .map(|r| r.into_inner())
175            .map_err(|status| {
176                SdkError::ApiError(SdkApiError {
177                    status,
178                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/DeleteTeam"
179                        .to_string(),
180                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
181                })
182            })
183    }
184
185    /// Retrieves the Team metadata.
186    ///
187    /// # Arguments
188    /// * `team_id` - The id of the team to retrieve.
189    pub async fn get(&self, team_id: u32) -> Result<GetTeamResponse> {
190        let request = make_request_with_metadata(
191            GetTeamRequest {
192                team_id: Some(TeamId { id: team_id }),
193            },
194            &self.metadata_map,
195        );
196
197        self.service_client
198            .lock()
199            .await
200            .get_team(request)
201            .await
202            .map(|r| r.into_inner())
203            .map_err(|status| {
204                SdkError::ApiError(SdkApiError {
205                    status,
206                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/GetTeam"
207                        .to_string(),
208                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
209                })
210            })
211    }
212
213    /// Retrieves the Team quota.
214    ///
215    /// # Arguments
216    /// * `team_id` - The id of the team to retrieve.
217    pub async fn get_quota(&self, team_id: u32) -> Result<GetTeamQuotaResponse> {
218        let request = make_request_with_metadata(
219            GetTeamQuotaRequest {
220                team_id: Some(TeamId { id: team_id }),
221            },
222            &self.metadata_map,
223        );
224
225        self.service_client
226            .lock()
227            .await
228            .get_team_quota(request)
229            .await
230            .map(|r| r.into_inner())
231            .map_err(|status| {
232                SdkError::ApiError(SdkApiError {
233                    status,
234                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/GetTeamQuota"
235                        .to_string(),
236                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
237                })
238            })
239    }
240
241    /// Sets the daily Team quota.
242    ///
243    /// # Arguments
244    /// * `team_id` - The id of the team to retrieve.
245    /// * `target_daily_quota` - The new daily quota for the team.
246    pub async fn set_daily_quota(
247        &self,
248        team_id: u32,
249        target_daily_quota: f32,
250    ) -> Result<SetDailyQuotaResponse> {
251        let request = make_request_with_metadata(
252            SetDailyQuotaRequest {
253                team_id: Some(TeamId { id: team_id }),
254                target_daily_quota,
255            },
256            &self.metadata_map,
257        );
258
259        self.service_client
260            .lock()
261            .await
262            .set_daily_quota(request)
263            .await
264            .map(|r| r.into_inner())
265            .map_err(|status| {
266                SdkError::ApiError(SdkApiError {
267                    status,
268                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/SetDailyQuota"
269                        .to_string(),
270                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
271                })
272            })
273    }
274
275    /// Moves the quota units from one team to the other.
276    ///
277    /// # Arguments
278    /// * `source_team_id` - The id of the team to move the quota from.
279    /// * `destination_team_id` - The id of the team to move the quota to.
280    /// * `units_to_move` - The number of units to move.
281    pub async fn move_quota(
282        &self,
283        source_team_id: u32,
284        destination_team_id: u32,
285        units_to_move: f64,
286    ) -> Result<MoveQuotaResponse> {
287        let request = make_request_with_metadata(
288            MoveQuotaRequest {
289                source_team: Some(TeamId { id: source_team_id }),
290                destination_team: Some(TeamId {
291                    id: destination_team_id,
292                }),
293                units_to_move,
294            },
295            &self.metadata_map,
296        );
297
298        self.service_client
299            .lock()
300            .await
301            .move_quota(request)
302            .await
303            .map(|r| r.into_inner())
304            .map_err(|status| {
305                SdkError::ApiError(SdkApiError {
306                    status,
307                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/MoveQuota"
308                        .to_string(),
309                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
310                })
311            })
312    }
313
314    /// Retrieves a list of all [`TeamInfo`]s.
315    ///     
316    /// # Returns
317    /// A list of all teams.
318    pub async fn list(&self) -> Result<ListTeamsResponse> {
319        let request = make_request_with_metadata(ListTeamsRequest {}, &self.metadata_map);
320
321        self.service_client
322            .lock()
323            .await
324            .list_teams(request)
325            .await
326            .map(|r| r.into_inner())
327            .map_err(|status| {
328                SdkError::ApiError(SdkApiError {
329                    status,
330                    endpoint: "/com.coralogixapis.aaa.organisations.v2.TeamService/ListTeams"
331                        .to_string(),
332                    feature_group: TEAMS_FEATURE_GROUP_ID.into(),
333                })
334            })
335    }
336}