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, ProcessorResponse};
57use crate::{CloudClient, Result};
58use serde::{Deserialize, Serialize};
59
60// ============================================================================
61// Models
62// ============================================================================
63
64/// Cloud account update request
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[serde(rename_all = "camelCase")]
67pub struct CloudAccountUpdateRequest {
68 /// Cloud account display name
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub name: Option<String>,
71
72 #[serde(skip_serializing_if = "Option::is_none")]
73 pub cloud_account_id: Option<i32>,
74
75 /// Cloud provider access key.
76 pub access_key_id: String,
77
78 /// Cloud provider secret key.
79 pub access_secret_key: String,
80
81 /// Cloud provider management console username.
82 pub console_username: String,
83
84 /// Cloud provider management console password.
85 pub console_password: String,
86
87 /// Optional. Cloud provider management console login URL.
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub sign_in_login_url: Option<String>,
90
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub command_type: Option<String>,
93}
94
95/// Cloud provider account information
96#[derive(Debug, Clone, Serialize, Deserialize)]
97#[serde(rename_all = "camelCase")]
98pub struct CloudAccount {
99 /// Cloud account ID
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub id: Option<i32>,
102
103 /// Cloud account display name
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub name: Option<String>,
106
107 /// Account status (e.g., "active", "error")
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub status: Option<String>,
110
111 /// Cloud provider (e.g., "AWS", "GCP", "Azure")
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub provider: Option<String>,
114
115 /// Cloud provider access key ID
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub access_key_id: Option<String>,
118
119 /// Cloud provider secret key (typically masked in responses)
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub access_secret_key: Option<String>,
122
123 /// AWS Console Role ARN (AWS-specific)
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub aws_console_role_arn: Option<String>,
126
127 /// AWS User ARN (AWS-specific)
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub aws_user_arn: Option<String>,
130
131 /// Cloud provider management console username
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub console_username: Option<String>,
134
135 /// Cloud provider management console password (typically masked)
136 #[serde(skip_serializing_if = "Option::is_none")]
137 pub console_password: Option<String>,
138
139 /// Cloud provider management console login URL
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub sign_in_login_url: Option<String>,
142
143 /// HATEOAS links for API navigation
144 #[serde(skip_serializing_if = "Option::is_none")]
145 pub links: Option<Vec<Link>>,
146}
147
148/// Cloud account create request
149#[derive(Debug, Clone, Serialize, Deserialize)]
150#[serde(rename_all = "camelCase")]
151pub struct CloudAccountCreateRequest {
152 /// Cloud account display name.
153 pub name: String,
154
155 /// Optional. Cloud provider. Default: 'AWS'
156 #[serde(skip_serializing_if = "Option::is_none")]
157 pub provider: Option<String>,
158
159 /// Cloud provider access key.
160 pub access_key_id: String,
161
162 /// Cloud provider secret key.
163 pub access_secret_key: String,
164
165 /// Cloud provider management console username.
166 pub console_username: String,
167
168 /// Cloud provider management console password.
169 pub console_password: String,
170
171 /// Cloud provider management console login URL.
172 pub sign_in_login_url: String,
173
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub command_type: Option<String>,
176}
177
178/// Cloud accounts response
179///
180/// Response from GET /cloud-accounts containing list of cloud provider integrations
181#[derive(Debug, Clone, Serialize, Deserialize)]
182#[serde(rename_all = "camelCase")]
183pub struct CloudAccounts {
184 /// Account ID
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub account_id: Option<i32>,
187
188 /// List of cloud provider accounts
189 #[serde(skip_serializing_if = "Option::is_none")]
190 pub cloud_accounts: Option<Vec<CloudAccount>>,
191
192 /// HATEOAS links for API navigation
193 #[serde(skip_serializing_if = "Option::is_none")]
194 pub links: Option<Vec<Link>>,
195}
196
197/// Task state update response
198#[derive(Debug, Clone, Serialize, Deserialize)]
199#[serde(rename_all = "camelCase")]
200pub struct TaskStateUpdate {
201 /// Task ID (UUID)
202 #[serde(skip_serializing_if = "Option::is_none")]
203 pub task_id: Option<String>,
204
205 /// Command type
206 #[serde(skip_serializing_if = "Option::is_none")]
207 pub command_type: Option<String>,
208
209 /// Task status
210 #[serde(skip_serializing_if = "Option::is_none")]
211 pub status: Option<String>,
212
213 /// Task description
214 #[serde(skip_serializing_if = "Option::is_none")]
215 pub description: Option<String>,
216
217 /// Timestamp
218 #[serde(skip_serializing_if = "Option::is_none")]
219 pub timestamp: Option<String>,
220
221 /// Task response with resource info
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub response: Option<ProcessorResponse>,
224
225 /// HATEOAS links
226 #[serde(skip_serializing_if = "Option::is_none")]
227 pub links: Option<Vec<Link>>,
228}
229
230// ============================================================================
231// Handler
232// ============================================================================
233
234/// Handler for cloud provider account operations
235///
236/// Manages integration with AWS, GCP, and Azure accounts, including
237/// credential management and provider-specific configurations.
238pub struct CloudAccountsHandler {
239 client: CloudClient,
240}
241
242impl CloudAccountsHandler {
243 /// Create a new handler
244 #[must_use]
245 pub fn new(client: CloudClient) -> Self {
246 Self { client }
247 }
248
249 /// Get cloud accounts
250 ///
251 /// Gets a list of all configured cloud accounts.
252 ///
253 /// # API Endpoint
254 ///
255 /// `GET /cloud-accounts`
256 ///
257 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `getCloudAccounts`
258 pub async fn get_cloud_accounts(&self) -> Result<CloudAccounts> {
259 self.client.get("/cloud-accounts").await
260 }
261
262 /// Create cloud account
263 ///
264 /// Creates a cloud account.
265 ///
266 /// # API Endpoint
267 ///
268 /// `POST /cloud-accounts`
269 ///
270 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `createCloudAccount`
271 pub async fn create_cloud_account(
272 &self,
273 request: &CloudAccountCreateRequest,
274 ) -> Result<TaskStateUpdate> {
275 self.client.post("/cloud-accounts", request).await
276 }
277
278 /// Delete cloud account
279 ///
280 /// Deletes a cloud account.
281 ///
282 /// # API Endpoint
283 ///
284 /// `DELETE /cloud-accounts/{cloudAccountId}`
285 ///
286 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `deleteCloudAccount`
287 pub async fn delete_cloud_account(&self, cloud_account_id: i32) -> Result<TaskStateUpdate> {
288 let response = self
289 .client
290 .delete_raw(&format!("/cloud-accounts/{cloud_account_id}"))
291 .await?;
292 serde_json::from_value(response).map_err(Into::into)
293 }
294
295 /// Get a single cloud account
296 ///
297 /// Gets details on a single cloud account.
298 ///
299 /// # API Endpoint
300 ///
301 /// `GET /cloud-accounts/{cloudAccountId}`
302 ///
303 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `getCloudAccountById`
304 pub async fn get_cloud_account_by_id(&self, cloud_account_id: i32) -> Result<CloudAccount> {
305 self.client
306 .get(&format!("/cloud-accounts/{cloud_account_id}"))
307 .await
308 }
309
310 /// Update cloud account
311 ///
312 /// Updates cloud account details.
313 ///
314 /// # API Endpoint
315 ///
316 /// `PUT /cloud-accounts/{cloudAccountId}`
317 ///
318 /// See [OpenAPI Spec](https://redis.io/docs/latest/operate/rc/api/api-reference/openapi.json) - `updateCloudAccount`
319 pub async fn update_cloud_account(
320 &self,
321 cloud_account_id: i32,
322 request: &CloudAccountUpdateRequest,
323 ) -> Result<TaskStateUpdate> {
324 self.client
325 .put(&format!("/cloud-accounts/{cloud_account_id}"), request)
326 .await
327 }
328}