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                access_policy: None,
112            },
113            &self.metadata_map,
114        );
115        self.service_client
116            .lock()
117            .await
118            .create_api_key(request)
119            .await
120            .map(|r| r.into_inner())
121            .map_err(|status| {
122                SdkError::ApiError(SdkApiError {
123                    status,
124                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/CreateApiKey"
125                        .into(),
126                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
127                })
128            })
129    }
130
131    /// Updates an API key.
132    ///
133    /// # Arguments
134    /// * `key_id` - The ID of the API key to update.
135    /// * `is_active` - Whether the API key should be active.
136    /// * `new_name` - The new name of the API key.
137    /// * `presets` - The new presets of the API key.
138    /// * `permissions` - The new permissions of the API key.
139    pub async fn update(
140        &self,
141        key_id: String,
142        is_active: Option<bool>,
143        new_name: Option<String>,
144        presets: Option<Vec<String>>,
145        permissions: Option<Vec<String>>,
146    ) -> Result<UpdateApiKeyResponse> {
147        let request = make_request_with_metadata(
148            UpdateApiKeyRequest {
149                key_id,
150                new_name,
151                is_active,
152                presets: presets.map(|p| Presets { presets: p }),
153                permissions: permissions.map(|p| Permissions { permissions: p }),
154                access_policy: None,
155            },
156            &self.metadata_map,
157        );
158        self.service_client
159            .lock()
160            .await
161            .update_api_key(request)
162            .await
163            .map(|r| r.into_inner())
164            .map_err(|status| {
165                SdkError::ApiError(SdkApiError {
166                    status,
167                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/UpdateApiKey"
168                        .into(),
169                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
170                })
171            })
172    }
173
174    /// Deletes an API key.
175    ///
176    /// # Arguments
177    /// * `key_id` - The ID of the API key to delete.
178    pub async fn delete(&self, key_id: String) -> Result<DeleteApiKeyResponse> {
179        let request =
180            make_request_with_metadata(DeleteApiKeyRequest { key_id }, &self.metadata_map);
181        self.service_client
182            .lock()
183            .await
184            .delete_api_key(request)
185            .await
186            .map(|r| r.into_inner())
187            .map_err(|status| {
188                SdkError::ApiError(SdkApiError {
189                    status,
190                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/DeleteApiKey"
191                        .into(),
192                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
193                })
194            })
195    }
196
197    /// Retrieves an API key by its ID.
198    ///
199    /// # Arguments
200    /// * `key_id` - The ID of the API key to retrieve.
201    pub async fn get(&self, key_id: String) -> Result<GetApiKeyResponse> {
202        let request = make_request_with_metadata(GetApiKeyRequest { key_id }, &self.metadata_map);
203        self.service_client
204            .lock()
205            .await
206            .get_api_key(request)
207            .await
208            .map(|r| r.into_inner())
209            .map_err(|status| {
210                SdkError::ApiError(SdkApiError {
211                    status,
212                    endpoint: "/com.coralogixapis.aaa.apikeys.v3.ApiKeysService/GetApiKey".into(),
213                    feature_group: API_KEYS_FEATURE_GROUP_ID.into(),
214                })
215            })
216    }
217}