cx_sdk/client/
apikeys.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 cx_api::proto::com::coralogixapis::aaa::apikeys::v3::{
16    CreateApiKeyRequest,
17    CreateApiKeyResponse,
18    DeleteApiKeyRequest,
19    DeleteApiKeyResponse,
20    GetApiKeyRequest,
21    GetApiKeyResponse,
22    Owner as OwnerWrapper,
23    UpdateApiKeyRequest,
24    UpdateApiKeyResponse,
25    api_keys_service_client::ApiKeysServiceClient,
26    create_api_key_request::KeyPermissions,
27    update_api_key_request::{
28        Permissions,
29        Presets,
30    },
31};
32use std::str::FromStr;
33
34use crate::{
35    CoralogixRegion,
36    auth::AuthContext,
37    error::{
38        Result,
39        SdkApiError,
40        SdkError,
41    },
42    metadata::CallProperties,
43    util::make_request_with_metadata,
44};
45
46use tokio::sync::Mutex;
47use tonic::{
48    metadata::MetadataMap,
49    transport::{
50        Channel,
51        ClientTlsConfig,
52        Endpoint,
53    },
54};
55
56pub use crate::com::coralogixapis::aaa::apikeys::v3::owner::Owner;
57
58const API_KEYS_FEATURE_GROUP_ID: &str = "aaa";
59
60/// The API Keys API client.
61/// Read more at <https://coralogix.com/docs/api-keys/>
62pub struct ApiKeysClient {
63    metadata_map: MetadataMap,
64    service_client: Mutex<ApiKeysServiceClient<Channel>>,
65}
66
67impl ApiKeysClient {
68    /// Creates a new client for the APIKeys API.
69    ///
70    /// # Arguments
71    /// * `auth_context` - The [`AuthContext`] to use for authentication.
72    /// * `region` - The [`CoralogixRegion`] to connect to.
73    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
74        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
75            .tls_config(ClientTlsConfig::new().with_native_roots())?
76            .connect_lazy();
77        let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
78        Ok(Self {
79            metadata_map: request_metadata.to_metadata_map(),
80            service_client: Mutex::new(ApiKeysServiceClient::new(channel)),
81        })
82    }
83
84    /// Creates a new API Key
85    ///
86    /// # Arguments
87    /// * `name` - The name of the API key.
88    /// * `owner` - The [`Owner`] of the API key.
89    /// * `presets` - The presets of the API key.
90    /// * `permissions` - The permissions of the API key.
91    /// * `hashed` - Whether the API key should be encrypted.
92    ///
93    /// Note that when the API key is hashed, it will not be possible to retrieve it later.
94    pub async fn create(
95        &self,
96        name: String,
97        owner: Option<Owner>,
98        presets: Vec<String>,
99        permissions: Vec<String>,
100        hashed: bool,
101    ) -> Result<CreateApiKeyResponse> {
102        let request = make_request_with_metadata(
103            CreateApiKeyRequest {
104                hashed,
105                name,
106                owner: owner.map(|o| OwnerWrapper { owner: Some(o) }),
107                key_permissions: Some(KeyPermissions {
108                    presets,
109                    permissions,
110                }),
111            },
112            &self.metadata_map,
113        );
114        self.service_client
115            .lock()
116            .await
117            .create_api_key(request)
118            .await
119            .map(|r| r.into_inner())
120            .map_err(|status| {
121                SdkError::ApiError(SdkApiError {
122                    status,
123                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/CreateApiKey"
124                        .into(),
125                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
126                })
127            })
128    }
129
130    /// Updates an API key.
131    ///
132    /// # Arguments
133    /// * `key_id` - The ID of the API key to update.
134    /// * `is_active` - Whether the API key should be active.
135    /// * `new_name` - The new name of the API key.
136    /// * `presets` - The new presets of the API key.
137    /// * `permissions` - The new permissions of the API key.
138    pub async fn update(
139        &self,
140        key_id: String,
141        is_active: Option<bool>,
142        new_name: Option<String>,
143        presets: Option<Vec<String>>,
144        permissions: Option<Vec<String>>,
145    ) -> Result<UpdateApiKeyResponse> {
146        let request = make_request_with_metadata(
147            UpdateApiKeyRequest {
148                key_id,
149                new_name,
150                is_active,
151                presets: presets.map(|p| Presets { presets: p }),
152                permissions: permissions.map(|p| Permissions { permissions: p }),
153            },
154            &self.metadata_map,
155        );
156        self.service_client
157            .lock()
158            .await
159            .update_api_key(request)
160            .await
161            .map(|r| r.into_inner())
162            .map_err(|status| {
163                SdkError::ApiError(SdkApiError {
164                    status,
165                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/UpdateApiKey"
166                        .into(),
167                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
168                })
169            })
170    }
171
172    /// Deletes an API key.
173    ///
174    /// # Arguments
175    /// * `key_id` - The ID of the API key to delete.
176    pub async fn delete(&self, key_id: String) -> Result<DeleteApiKeyResponse> {
177        let request =
178            make_request_with_metadata(DeleteApiKeyRequest { key_id }, &self.metadata_map);
179        self.service_client
180            .lock()
181            .await
182            .delete_api_key(request)
183            .await
184            .map(|r| r.into_inner())
185            .map_err(|status| {
186                SdkError::ApiError(SdkApiError {
187                    status,
188                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/DeleteApiKey"
189                        .into(),
190                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
191                })
192            })
193    }
194
195    /// Retrieves an API key by its ID.
196    ///
197    /// # Arguments
198    /// * `key_id` - The ID of the API key to retrieve.
199    pub async fn get(&self, key_id: String) -> Result<GetApiKeyResponse> {
200        let request = make_request_with_metadata(GetApiKeyRequest { key_id }, &self.metadata_map);
201        self.service_client
202            .lock()
203            .await
204            .get_api_key(request)
205            .await
206            .map(|r| r.into_inner())
207            .map_err(|status| {
208                SdkError::ApiError(SdkApiError {
209                    status,
210                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/GetApiKey".into(),
211                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
212                })
213            })
214    }
215}