redis_cloud/cloud_accounts.rs
1//! Cloud provider account management operations and models
2//!
3//! This module handles the integration between Redis Cloud and your cloud provider
4//! accounts (AWS, GCP, Azure). It manages cloud account credentials, access keys,
5//! and provider-specific configurations.
6//!
7//! # Overview
8//!
9//! Cloud accounts are the bridge between Redis Cloud and your infrastructure provider.
10//! They store the credentials and permissions needed for Redis Cloud to provision
11//! resources in your cloud environment.
12//!
13//! # Supported Providers
14//!
15//! - **AWS**: Amazon Web Services accounts with IAM roles or access keys
16//! - **GCP**: Google Cloud Platform projects with service accounts
17//! - **Azure**: Microsoft Azure subscriptions with service principals
18//!
19//! # Key Features
20//!
21//! - **Account Registration**: Register cloud provider accounts with Redis Cloud
22//! - **Credential Management**: Securely store and manage cloud credentials
23//! - **Access Key Operations**: Create, update, and delete cloud access keys
24//! - **Provider Details**: Retrieve provider-specific account information
25//! - **Multi-cloud Support**: Manage accounts across different cloud providers
26//!
27//! # API Reference
28//!
29//! All operations in this module map to the Redis Cloud REST API's Cloud Accounts endpoints.
30//! For detailed API documentation, see the [Redis Cloud OpenAPI Specification].
31//!
32//! [Redis Cloud OpenAPI Specification]: https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json
33//!
34//! # Example Usage
35//!
36//! ```no_run
37//! use redis_cloud::{CloudClient, CloudAccountHandler};
38//!
39//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
40//! let client = CloudClient::builder()
41//! .api_key("your-api-key")
42//! .api_secret("your-api-secret")
43//! .build()?;
44//!
45//! let handler = CloudAccountHandler::new(client);
46//!
47//! // List all cloud accounts
48//! let accounts = handler.get_cloud_accounts().await?;
49//!
50//! // Get specific account details (account ID 123)
51//! let account = handler.get_cloud_account_by_id(123).await?;
52//! # Ok(())
53//! # }
54//! ```
55
56use crate::types::Link;
57pub use crate::types::TaskStateUpdate;
58use crate::{CloudClient, Result};
59use serde::{Deserialize, Serialize};
60
61// ============================================================================
62// Models
63// ============================================================================
64
65/// Cloud account update request
66#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(rename_all = "camelCase")]
68pub struct CloudAccountUpdateRequest {
69 /// Cloud account display name
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub name: Option<String>,
72
73 /// Cloud account ID being updated. Server-populated from the path.
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub cloud_account_id: Option<i32>,
76
77 /// Cloud provider access key.
78 pub access_key_id: String,
79
80 /// Cloud provider secret key.
81 pub access_secret_key: String,
82
83 /// Cloud provider management console username.
84 pub console_username: String,
85
86 /// Cloud provider management console password.
87 pub console_password: String,
88
89 /// Optional. Cloud provider management console login URL.
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub sign_in_login_url: Option<String>,
92
93 /// Read-only on the response; populated by the server with the
94 /// operation type (e.g. `"UPDATE_CLOUD_ACCOUNT"`).
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub command_type: Option<String>,
97}
98
99/// Cloud provider account information
100#[derive(Debug, Clone, Serialize, Deserialize)]
101#[serde(rename_all = "camelCase")]
102pub struct CloudAccount {
103 /// Cloud account ID
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub id: Option<i32>,
106
107 /// Cloud account display name
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub name: Option<String>,
110
111 /// Account status (e.g., "active", "error")
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub status: Option<String>,
114
115 /// Cloud provider (e.g., "AWS", "GCP", "Azure")
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub provider: Option<String>,
118
119 /// Cloud provider access key ID
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub access_key_id: Option<String>,
122
123 /// Cloud provider secret key (typically masked in responses)
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub access_secret_key: Option<String>,
126
127 /// AWS Console Role ARN (AWS-specific)
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub aws_console_role_arn: Option<String>,
130
131 /// AWS User ARN (AWS-specific)
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub aws_user_arn: Option<String>,
134
135 /// Cloud provider management console username
136 #[serde(skip_serializing_if = "Option::is_none")]
137 pub console_username: Option<String>,
138
139 /// Cloud provider management console password (typically masked)
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub console_password: Option<String>,
142
143 /// Cloud provider management console login URL
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub sign_in_login_url: Option<String>,
146
147 /// HATEOAS links for API navigation
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub links: Option<Vec<Link>>,
150}
151
152/// Cloud account create request
153#[derive(Debug, Clone, Serialize, Deserialize)]
154#[serde(rename_all = "camelCase")]
155pub struct CloudAccountCreateRequest {
156 /// Cloud account display name.
157 pub name: String,
158
159 /// Optional. Cloud provider. Default: 'AWS'
160 #[serde(skip_serializing_if = "Option::is_none")]
161 pub provider: Option<String>,
162
163 /// Cloud provider access key.
164 pub access_key_id: String,
165
166 /// Cloud provider secret key.
167 pub access_secret_key: String,
168
169 /// Cloud provider management console username.
170 pub console_username: String,
171
172 /// Cloud provider management console password.
173 pub console_password: String,
174
175 /// Cloud provider management console login URL.
176 pub sign_in_login_url: String,
177
178 /// Read-only on the response; populated by the server with the
179 /// operation type (e.g. `"CREATE_CLOUD_ACCOUNT"`).
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub command_type: Option<String>,
182}
183
184/// Cloud accounts response
185///
186/// Response from GET /cloud-accounts containing list of cloud provider integrations
187#[derive(Debug, Clone, Serialize, Deserialize)]
188#[serde(rename_all = "camelCase")]
189pub struct CloudAccounts {
190 /// Account ID
191 #[serde(skip_serializing_if = "Option::is_none")]
192 pub account_id: Option<i32>,
193
194 /// List of cloud provider accounts
195 #[serde(skip_serializing_if = "Option::is_none")]
196 pub cloud_accounts: Option<Vec<CloudAccount>>,
197
198 /// HATEOAS links for API navigation
199 #[serde(skip_serializing_if = "Option::is_none")]
200 pub links: Option<Vec<Link>>,
201}
202
203// ============================================================================
204// Handler
205// ============================================================================
206
207/// Handler for cloud provider account operations
208///
209/// Manages integration with AWS, GCP, and Azure accounts, including
210/// credential management and provider-specific configurations.
211pub struct CloudAccountsHandler {
212 client: CloudClient,
213}
214
215impl CloudAccountsHandler {
216 /// Create a new handler
217 #[must_use]
218 pub fn new(client: CloudClient) -> Self {
219 Self { client }
220 }
221
222 /// Get cloud accounts
223 ///
224 /// Gets a list of all configured cloud accounts.
225 ///
226 /// # API Endpoint
227 ///
228 /// `GET /cloud-accounts`
229 ///
230 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `getCloudAccounts`
231 pub async fn get_cloud_accounts(&self) -> Result<CloudAccounts> {
232 self.client.get("/cloud-accounts").await
233 }
234
235 /// Create cloud account
236 ///
237 /// Creates a cloud account.
238 ///
239 /// # API Endpoint
240 ///
241 /// `POST /cloud-accounts`
242 ///
243 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `createCloudAccount`
244 pub async fn create_cloud_account(
245 &self,
246 request: &CloudAccountCreateRequest,
247 ) -> Result<TaskStateUpdate> {
248 self.client.post("/cloud-accounts", request).await
249 }
250
251 /// Delete cloud account
252 ///
253 /// Deletes a cloud account.
254 ///
255 /// # API Endpoint
256 ///
257 /// `DELETE /cloud-accounts/{cloudAccountId}`
258 ///
259 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `deleteCloudAccount`
260 pub async fn delete_cloud_account(&self, cloud_account_id: i32) -> Result<TaskStateUpdate> {
261 let response = self
262 .client
263 .delete_raw(&format!("/cloud-accounts/{cloud_account_id}"))
264 .await?;
265 serde_json::from_value(response).map_err(Into::into)
266 }
267
268 /// Get a single cloud account
269 ///
270 /// Gets details on a single cloud account.
271 ///
272 /// # API Endpoint
273 ///
274 /// `GET /cloud-accounts/{cloudAccountId}`
275 ///
276 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `getCloudAccountById`
277 pub async fn get_cloud_account_by_id(&self, cloud_account_id: i32) -> Result<CloudAccount> {
278 self.client
279 .get(&format!("/cloud-accounts/{cloud_account_id}"))
280 .await
281 }
282
283 /// Update cloud account
284 ///
285 /// Updates cloud account details.
286 ///
287 /// # API Endpoint
288 ///
289 /// `PUT /cloud-accounts/{cloudAccountId}`
290 ///
291 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `updateCloudAccount`
292 pub async fn update_cloud_account(
293 &self,
294 cloud_account_id: i32,
295 request: &CloudAccountUpdateRequest,
296 ) -> Result<TaskStateUpdate> {
297 self.client
298 .put(&format!("/cloud-accounts/{cloud_account_id}"), request)
299 .await
300 }
301
302 // ============================================================================
303 // Simplified aliases
304 // ============================================================================
305
306 /// List cloud accounts (simplified)
307 ///
308 /// Alias for [`get_cloud_accounts`](Self::get_cloud_accounts).
309 ///
310 /// # Example
311 ///
312 /// ```no_run
313 /// use redis_cloud::CloudClient;
314 ///
315 /// # async fn example() -> redis_cloud::Result<()> {
316 /// let client = CloudClient::builder()
317 /// .api_key("your-api-key")
318 /// .api_secret("your-api-secret")
319 /// .build()?;
320 ///
321 /// let accounts = client.cloud_accounts().list().await?;
322 /// # Ok(())
323 /// # }
324 /// ```
325 pub async fn list(&self) -> Result<CloudAccounts> {
326 self.get_cloud_accounts().await
327 }
328
329 /// Create a cloud account (simplified)
330 ///
331 /// Alias for [`create_cloud_account`](Self::create_cloud_account).
332 ///
333 /// # Arguments
334 ///
335 /// * `request` - The cloud account creation request
336 ///
337 /// # Example
338 ///
339 /// ```no_run
340 /// use redis_cloud::CloudClient;
341 /// use redis_cloud::cloud_accounts::CloudAccountCreateRequest;
342 ///
343 /// # async fn example() -> redis_cloud::Result<()> {
344 /// let client = CloudClient::builder()
345 /// .api_key("your-api-key")
346 /// .api_secret("your-api-secret")
347 /// .build()?;
348 ///
349 /// let request = CloudAccountCreateRequest {
350 /// name: "my-aws-account".to_string(),
351 /// provider: Some("AWS".to_string()),
352 /// access_key_id: "key".to_string(),
353 /// access_secret_key: "secret".to_string(),
354 /// console_username: "user".to_string(),
355 /// console_password: "pass".to_string(),
356 /// sign_in_login_url: "https://console.aws.amazon.com".to_string(),
357 /// command_type: None,
358 /// };
359 ///
360 /// let task = client.cloud_accounts().create(&request).await?;
361 /// # Ok(())
362 /// # }
363 /// ```
364 pub async fn create(&self, request: &CloudAccountCreateRequest) -> Result<TaskStateUpdate> {
365 self.create_cloud_account(request).await
366 }
367
368 /// Delete a cloud account (simplified)
369 ///
370 /// Alias for [`delete_cloud_account`](Self::delete_cloud_account).
371 ///
372 /// # Arguments
373 ///
374 /// * `cloud_account_id` - The cloud account ID
375 ///
376 /// # Example
377 ///
378 /// ```no_run
379 /// use redis_cloud::CloudClient;
380 ///
381 /// # async fn example() -> redis_cloud::Result<()> {
382 /// let client = CloudClient::builder()
383 /// .api_key("your-api-key")
384 /// .api_secret("your-api-secret")
385 /// .build()?;
386 ///
387 /// let task = client.cloud_accounts().delete(123).await?;
388 /// # Ok(())
389 /// # }
390 /// ```
391 pub async fn delete(&self, cloud_account_id: i32) -> Result<TaskStateUpdate> {
392 self.delete_cloud_account(cloud_account_id).await
393 }
394
395 /// Get a cloud account by ID (simplified)
396 ///
397 /// Alias for [`get_cloud_account_by_id`](Self::get_cloud_account_by_id).
398 ///
399 /// # Arguments
400 ///
401 /// * `cloud_account_id` - The cloud account ID
402 ///
403 /// # Example
404 ///
405 /// ```no_run
406 /// use redis_cloud::CloudClient;
407 ///
408 /// # async fn example() -> redis_cloud::Result<()> {
409 /// let client = CloudClient::builder()
410 /// .api_key("your-api-key")
411 /// .api_secret("your-api-secret")
412 /// .build()?;
413 ///
414 /// let account = client.cloud_accounts().get(123).await?;
415 /// # Ok(())
416 /// # }
417 /// ```
418 pub async fn get(&self, cloud_account_id: i32) -> Result<CloudAccount> {
419 self.get_cloud_account_by_id(cloud_account_id).await
420 }
421
422 /// Update a cloud account (simplified)
423 ///
424 /// Alias for [`update_cloud_account`](Self::update_cloud_account).
425 ///
426 /// # Arguments
427 ///
428 /// * `cloud_account_id` - The cloud account ID
429 /// * `request` - The cloud account update request
430 ///
431 /// # Example
432 ///
433 /// ```no_run
434 /// use redis_cloud::CloudClient;
435 /// use redis_cloud::cloud_accounts::CloudAccountUpdateRequest;
436 ///
437 /// # async fn example() -> redis_cloud::Result<()> {
438 /// let client = CloudClient::builder()
439 /// .api_key("your-api-key")
440 /// .api_secret("your-api-secret")
441 /// .build()?;
442 ///
443 /// let request = CloudAccountUpdateRequest {
444 /// name: Some("renamed-account".to_string()),
445 /// cloud_account_id: None,
446 /// access_key_id: "key".to_string(),
447 /// access_secret_key: "secret".to_string(),
448 /// console_username: "user".to_string(),
449 /// console_password: "pass".to_string(),
450 /// sign_in_login_url: None,
451 /// command_type: None,
452 /// };
453 ///
454 /// let task = client.cloud_accounts().update(123, &request).await?;
455 /// # Ok(())
456 /// # }
457 /// ```
458 pub async fn update(
459 &self,
460 cloud_account_id: i32,
461 request: &CloudAccountUpdateRequest,
462 ) -> Result<TaskStateUpdate> {
463 self.update_cloud_account(cloud_account_id, request).await
464 }
465}