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//! # Example Usage
28//!
29//! ```no_run
30//! use redis_cloud::{CloudClient, CloudAccountHandler};
31//!
32//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
33//! let client = CloudClient::builder()
34//!     .api_key("your-api-key")
35//!     .api_secret("your-api-secret")
36//!     .build()?;
37//!
38//! let handler = CloudAccountHandler::new(client);
39//!
40//! // List all cloud accounts
41//! let accounts = handler.get_cloud_accounts().await?;
42//!
43//! // Get specific account details (account ID 123)
44//! let account = handler.get_cloud_account_by_id(123).await?;
45//! # Ok(())
46//! # }
47//! ```
48
49use crate::{CloudClient, Result};
50use serde::{Deserialize, Serialize};
51use serde_json::Value;
52use std::collections::HashMap;
53
54// ============================================================================
55// Models
56// ============================================================================
57
58/// Cloud Account definition
59#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(rename_all = "camelCase")]
61pub struct CloudAccountUpdateRequest {
62    /// name
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub name: Option<String>,
65
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub cloud_account_id: Option<i32>,
68
69    /// Cloud provider access key.
70    pub access_key_id: String,
71
72    /// Cloud provider secret key.
73    pub access_secret_key: String,
74
75    /// Cloud provider management console username.
76    pub console_username: String,
77
78    /// Cloud provider management console password.
79    pub console_password: String,
80
81    /// Optional. Cloud provider management console login URL.
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub sign_in_login_url: Option<String>,
84
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub command_type: Option<String>,
87
88    /// Additional fields from the API
89    #[serde(flatten)]
90    pub extra: Value,
91}
92
93/// RedisLabs Cloud Account information
94#[derive(Debug, Clone, Serialize, Deserialize)]
95#[serde(rename_all = "camelCase")]
96pub struct CloudAccount {
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub id: Option<i32>,
99
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub name: Option<String>,
102
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub status: Option<String>,
105
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub access_key_id: Option<String>,
108
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub sign_in_login_url: Option<String>,
111
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub provider: Option<String>,
114
115    /// HATEOAS links
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub links: Option<Vec<HashMap<String, Value>>>,
118
119    /// Additional fields from the API
120    #[serde(flatten)]
121    pub extra: Value,
122}
123
124/// Cloud Account definition
125#[derive(Debug, Clone, Serialize, Deserialize)]
126#[serde(rename_all = "camelCase")]
127pub struct CloudAccountCreateRequest {
128    /// Cloud account display name.
129    pub name: String,
130
131    /// Optional. Cloud provider. Default: 'AWS'
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub provider: Option<String>,
134
135    /// Cloud provider access key.
136    pub access_key_id: String,
137
138    /// Cloud provider secret key.
139    pub access_secret_key: String,
140
141    /// Cloud provider management console username.
142    pub console_username: String,
143
144    /// Cloud provider management console password.
145    pub console_password: String,
146
147    /// Cloud provider management console login URL.
148    pub sign_in_login_url: String,
149
150    #[serde(skip_serializing_if = "Option::is_none")]
151    pub command_type: Option<String>,
152
153    /// Additional fields from the API
154    #[serde(flatten)]
155    pub extra: Value,
156}
157
158/// RedisLabs Cloud Accounts information
159#[derive(Debug, Clone, Serialize, Deserialize)]
160#[serde(rename_all = "camelCase")]
161pub struct CloudAccounts {
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub account_id: Option<i32>,
164
165    /// HATEOAS links
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub links: Option<Vec<HashMap<String, Value>>>,
168
169    /// Additional fields from the API
170    #[serde(flatten)]
171    pub extra: Value,
172}
173
174/// ProcessorResponse
175#[derive(Debug, Clone, Serialize, Deserialize)]
176#[serde(rename_all = "camelCase")]
177pub struct ProcessorResponse {
178    #[serde(skip_serializing_if = "Option::is_none")]
179    pub resource_id: Option<i32>,
180
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub additional_resource_id: Option<i32>,
183
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub resource: Option<HashMap<String, Value>>,
186
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub error: Option<String>,
189
190    #[serde(skip_serializing_if = "Option::is_none")]
191    pub additional_info: Option<String>,
192
193    /// Additional fields from the API
194    #[serde(flatten)]
195    pub extra: Value,
196}
197
198/// TaskStateUpdate
199#[derive(Debug, Clone, Serialize, Deserialize)]
200#[serde(rename_all = "camelCase")]
201pub struct TaskStateUpdate {
202    #[serde(skip_serializing_if = "Option::is_none")]
203    pub task_id: Option<String>,
204
205    #[serde(skip_serializing_if = "Option::is_none")]
206    pub command_type: Option<String>,
207
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub status: Option<String>,
210
211    #[serde(skip_serializing_if = "Option::is_none")]
212    pub description: Option<String>,
213
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub timestamp: Option<String>,
216
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub response: Option<ProcessorResponse>,
219
220    /// HATEOAS links
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub links: Option<Vec<HashMap<String, Value>>>,
223
224    /// Additional fields from the API
225    #[serde(flatten)]
226    pub extra: Value,
227}
228
229// ============================================================================
230// Handler
231// ============================================================================
232
233/// Handler for cloud provider account operations
234///
235/// Manages integration with AWS, GCP, and Azure accounts, including
236/// credential management and provider-specific configurations.
237pub struct CloudAccountsHandler {
238    client: CloudClient,
239}
240
241impl CloudAccountsHandler {
242    /// Create a new handler
243    pub fn new(client: CloudClient) -> Self {
244        Self { client }
245    }
246
247    /// Get cloud accounts
248    /// Gets a list of all configured cloud accounts.
249    ///
250    /// GET /cloud-accounts
251    pub async fn get_cloud_accounts(&self) -> Result<CloudAccounts> {
252        self.client.get("/cloud-accounts").await
253    }
254
255    /// Create cloud account
256    /// Creates a cloud account.
257    ///
258    /// POST /cloud-accounts
259    pub async fn create_cloud_account(
260        &self,
261        request: &CloudAccountCreateRequest,
262    ) -> Result<TaskStateUpdate> {
263        self.client.post("/cloud-accounts", request).await
264    }
265
266    /// Delete cloud account
267    /// Deletes a cloud account.
268    ///
269    /// DELETE /cloud-accounts/{cloudAccountId}
270    pub async fn delete_cloud_account(&self, cloud_account_id: i32) -> Result<TaskStateUpdate> {
271        let response = self
272            .client
273            .delete_raw(&format!("/cloud-accounts/{}", cloud_account_id))
274            .await?;
275        serde_json::from_value(response).map_err(Into::into)
276    }
277
278    /// Get a single cloud account
279    /// Gets details on a single cloud account.
280    ///
281    /// GET /cloud-accounts/{cloudAccountId}
282    pub async fn get_cloud_account_by_id(&self, cloud_account_id: i32) -> Result<CloudAccount> {
283        self.client
284            .get(&format!("/cloud-accounts/{}", cloud_account_id))
285            .await
286    }
287
288    /// Update cloud account
289    /// Updates cloud account details.
290    ///
291    /// PUT /cloud-accounts/{cloudAccountId}
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}