redis_cloud/lib.rs
1// Allow doc strings with quoted values like 'true'/'false' from OpenAPI spec
2#![allow(clippy::doc_link_with_quotes)]
3// Every public item must carry a docstring. Closed the 368 existing
4// gaps under #80; this lint keeps the bar from regressing.
5#![deny(missing_docs)]
6#![deny(rustdoc::broken_intra_doc_links)]
7
8//! Redis Cloud REST API Client
9//!
10//! A comprehensive Rust client for the Redis Cloud REST API, providing full access to
11//! subscription management, database operations, billing, monitoring, and advanced features
12//! like VPC peering, SSO/SAML, and Private Service Connect.
13//!
14//! ## Features
15//!
16//! - **Subscription Management**: Create, update, delete subscriptions across AWS, GCP, Azure
17//! - **Database Operations**: Full CRUD operations, backups, imports, metrics
18//! - **Advanced Networking**: VPC peering, Transit Gateway, Private Service Connect
19//! - **Security & Access**: ACLs, SSO/SAML integration, API key management
20//! - **Monitoring & Billing**: Comprehensive metrics, logs, billing and payment management
21//! - **Enterprise Features**: Active-Active databases (CRDB), fixed/essentials plans
22//!
23//! ## Quick Start
24//!
25//! ```rust,no_run
26//! use redis_cloud::CloudClient;
27//!
28//! #[tokio::main]
29//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
30//! let client = CloudClient::builder()
31//! .api_key(std::env::var("REDIS_CLOUD_API_KEY")?)
32//! .api_secret(std::env::var("REDIS_CLOUD_API_SECRET")?)
33//! .build()?;
34//!
35//! // List all databases in subscription 123 (Vec<Database>, no wrapper)
36//! let databases = client.databases().list(123).await?;
37//! println!("Found {} databases", databases.len());
38//!
39//! Ok(())
40//! }
41//! ```
42//!
43//! ## Core Usage Patterns
44//!
45//! ### Client Creation
46//!
47//! The client uses a builder pattern for flexible configuration:
48//!
49//! ```rust,no_run
50//! use redis_cloud::CloudClient;
51//!
52//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
53//! // Basic client with default settings
54//! let client = CloudClient::builder()
55//! .api_key("your-api-key")
56//! .api_secret("your-api-secret")
57//! .build()?;
58//!
59//! // Custom configuration
60//! let client2 = CloudClient::builder()
61//! .api_key("your-api-key")
62//! .api_secret("your-api-secret")
63//! .base_url("https://api.redislabs.com/v1".to_string())
64//! .timeout(std::time::Duration::from_secs(60))
65//! .build()?;
66//! # Ok(())
67//! # }
68//! ```
69//!
70//! ### Typed vs Raw API
71//!
72//! This client offers typed handlers for common operations as well as raw helpers when you
73//! need full control over request/response payloads:
74//!
75//! - Prefer typed handlers (e.g., `CloudDatabaseHandler`) for structured, ergonomic access.
76//! - Use raw helpers for passthroughs: `get_raw`, `post_raw`, `put_raw`, `patch_raw`, `delete_raw`.
77//!
78//! ```rust,no_run
79//! use redis_cloud::CloudClient;
80//! use serde_json::json;
81//!
82//! # #[tokio::main]
83//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
84//! let client = CloudClient::builder()
85//! .api_key("key")
86//! .api_secret("secret")
87//! .build()?;
88//!
89//! // Raw call example
90//! let created = client.post_raw("/subscriptions", json!({ "name": "example" })).await?;
91//! println!("{}", created);
92//! # Ok(())
93//! # }
94//! ```
95//!
96//! ### Working with Subscriptions
97//!
98//! ```rust,no_run
99//! use redis_cloud::{CloudClient, SubscriptionHandler};
100//! use serde_json::json;
101//!
102//! # #[tokio::main]
103//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
104//! let client = CloudClient::builder()
105//! .api_key("key")
106//! .api_secret("secret")
107//! .build()?;
108//!
109//! let sub_handler = SubscriptionHandler::new(client.clone());
110//!
111//! // List subscriptions
112//! let subscriptions = sub_handler.list().await?;
113//!
114//! // Create a new subscription using raw API
115//! let new_subscription = json!({
116//! "name": "my-redis-subscription",
117//! "provider": "AWS",
118//! "region": "us-east-1",
119//! "plan": "cache.m5.large"
120//! });
121//! let created = client.post_raw("/subscriptions", new_subscription).await?;
122//! # Ok(())
123//! # }
124//! ```
125//!
126//! ### Database Management
127//!
128//! ```rust,no_run
129//! use redis_cloud::{CloudClient, DatabaseHandler};
130//! use serde_json::json;
131//!
132//! # #[tokio::main]
133//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
134//! let client = CloudClient::builder()
135//! .api_key("key")
136//! .api_secret("secret")
137//! .build()?;
138//!
139//! let db_handler = DatabaseHandler::new(client.clone());
140//!
141//! // Create database using raw API
142//! let database_config = json!({
143//! "name": "my-database",
144//! "memoryLimitInGb": 1.0,
145//! "support_oss_cluster_api": false,
146//! "replication": true
147//! });
148//! let database = client.post_raw("/subscriptions/123/databases", database_config).await?;
149//!
150//! // Get database info
151//! let db_info = db_handler.get_subscription_database_by_id(123, 456).await?;
152//! # Ok(())
153//! # }
154//! ```
155//!
156//! ### Advanced Features
157//!
158//! #### VPC Peering
159//! ```rust,no_run
160//! use redis_cloud::{CloudClient, VpcPeeringHandler};
161//! use redis_cloud::connectivity::VpcPeeringCreateRequest;
162//!
163//! # #[tokio::main]
164//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
165//! let client = CloudClient::builder()
166//! .api_key("key")
167//! .api_secret("secret")
168//! .build()?;
169//!
170//! let handler = VpcPeeringHandler::new(client);
171//!
172//! // Construct a provider-targeted body — `for_aws` pre-populates the
173//! // spec's required AWS fields with the correct wire names.
174//! let mut request = VpcPeeringCreateRequest::for_aws(
175//! "us-east-1",
176//! "123456789012",
177//! "vpc-12345678",
178//! );
179//! request.vpc_cidr = Some("10.0.0.0/16".to_string());
180//!
181//! let task = handler.create(123, &request).await?;
182//! println!("Peering create task: {:?}", task.task_id);
183//! # Ok(())
184//! # }
185//! ```
186//!
187//! #### SSO/SAML Management
188//! ```rust,no_run
189//! use redis_cloud::{CloudClient, AccountHandler};
190//! use serde_json::json;
191//!
192//! # #[tokio::main]
193//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
194//! let client = CloudClient::builder()
195//! .api_key("key")
196//! .api_secret("secret")
197//! .build()?;
198//!
199//! let sso_handler = AccountHandler::new(client.clone());
200//!
201//! // Configure SSO using raw API
202//! let sso_config = json!({
203//! "enabled": true,
204//! "auto_provision": true
205//! });
206//! let config = client.put_raw("/sso", sso_config).await?;
207//! # Ok(())
208//! # }
209//! ```
210//!
211//! #### Account Information (Typed)
212//! ```rust,no_run
213//! use redis_cloud::{AccountHandler, CloudClient};
214//!
215//! # #[tokio::main]
216//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
217//! let client = CloudClient::builder()
218//! .api_key("key")
219//! .api_secret("secret")
220//! .build()?;
221//!
222//! let account = AccountHandler::new(client.clone());
223//! let account_info = account.get_current_account().await?;
224//! # let _ = account_info;
225//! # Ok(())
226//! # }
227//! ```
228//!
229//! ## Error Handling
230//!
231//! The client provides comprehensive error handling for different failure scenarios:
232//!
233//! ```rust,no_run
234//! use redis_cloud::{CloudClient, CloudError, DatabaseHandler};
235//!
236//! # #[tokio::main]
237//! # async fn main() {
238//! let client = CloudClient::builder()
239//! .api_key("key")
240//! .api_secret("secret")
241//! .build().unwrap();
242//!
243//! let db_handler = DatabaseHandler::new(client.clone());
244//!
245//! match db_handler.get_subscription_database_by_id(123, 456).await {
246//! Ok(database) => println!("Database: {:?}", database),
247//! Err(CloudError::ApiError { code: 404, .. }) => {
248//! println!("Database not found");
249//! },
250//! Err(CloudError::AuthenticationFailed { message }) => {
251//! println!("Invalid API credentials");
252//! },
253//! Err(e) => println!("Other error: {}", e),
254//! }
255//! # }
256//! ```
257//!
258//! ## Handler Overview
259//!
260//! The client provides specialized handlers for different API domains:
261//!
262//! | Handler | Purpose | Key Operations |
263//! |---------|---------|----------------|
264//! | [`SubscriptionHandler`] | Pro subscriptions | create, list, update, delete, pricing |
265//! | [`FixedSubscriptionHandler`] | Essentials subscriptions | fixed plans, create, update, delete |
266//! | [`DatabaseHandler`] | Pro databases | create, backup, import, metrics, resize |
267//! | [`FixedDatabaseHandler`] | Essentials databases | fixed capacity, backup, import |
268//! | [`AccountHandler`] | Account management | info, API keys, payment methods, SSO |
269//! | [`UserHandler`] | User management | create, update, delete, invite, roles |
270//! | [`AclHandler`] | Access control | users, roles, Redis rules, database ACLs |
271//! | [`VpcPeeringHandler`] | VPC peering | standard and Active-Active peering |
272//! | [`TransitGatewayHandler`] | AWS Transit Gateway | attachments, invitations, CIDR updates |
273//! | [`PscHandler`] | GCP Private Service Connect | endpoints (standard and Active-Active) |
274//! | [`PrivateLinkHandler`] | AWS PrivateLink | services, connections, endpoints |
275//! | [`CostReportHandler`] | Cost reports | FOCUS-format billing exports |
276//! | [`CloudAccountHandler`] | Cloud providers | AWS, GCP, Azure account integration |
277//! | [`TaskHandler`] | Async operations | track long-running operations |
278//!
279//! ## Authentication
280//!
281//! Redis Cloud uses API key authentication with two required headers:
282//! - `x-api-key`: Your API key
283//! - `x-api-secret-key`: Your API secret
284//!
285//! These credentials can be obtained from the Redis Cloud console under Account Settings > API Keys.
286//!
287//! Environment variables commonly used with this client:
288//! - `REDIS_CLOUD_API_KEY`
289//! - `REDIS_CLOUD_API_SECRET`
290//! - Optional: set a custom base URL via the builder for non‑prod/test environments (defaults to `https://api.redislabs.com/v1`).
291
292pub mod client;
293pub mod error;
294
295#[cfg(test)]
296mod lib_tests;
297
298// Re-export client types
299pub use client::{CloudClient, CloudClientBuilder};
300
301// Re-export error types
302pub use error::{CloudError, Result};
303
304// Re-export Tower integration when feature is enabled
305#[cfg(feature = "tower-integration")]
306pub use client::tower_support;
307
308// Test support module - only available with test-support feature
309#[cfg(feature = "test-support")]
310pub mod testing;
311
312// Types module for shared models
313pub mod types;
314
315// Handler modules - each handles a specific API domain
316pub mod account;
317pub mod acl;
318pub mod cloud_accounts;
319pub mod connectivity;
320pub mod cost_report;
321pub mod fixed;
322pub mod flexible;
323pub mod tasks;
324pub mod users;
325
326// Backward compatibility module aliases
327pub use fixed::databases as fixed_databases;
328pub use fixed::subscriptions as fixed_subscriptions;
329pub use flexible::databases;
330pub use flexible::subscriptions;
331
332// Re-export handlers with standard naming
333pub use account::AccountHandler;
334pub use acl::AclHandler;
335pub use cloud_accounts::CloudAccountsHandler as CloudAccountHandler;
336
337// Connectivity handlers
338pub use connectivity::private_link::PrivateLinkHandler;
339pub use connectivity::psc::PscHandler;
340pub use connectivity::transit_gateway::TransitGatewayHandler;
341pub use connectivity::vpc_peering::VpcPeeringHandler;
342// Connectivity types
343pub use connectivity::{PrincipalType, PrivateLinkAddPrincipalRequest, PrivateLinkCreateRequest};
344// Legacy connectivity export for backward compatibility
345pub use connectivity::ConnectivityHandler;
346
347// Fixed plan handlers
348pub use fixed::databases::FixedDatabaseHandler;
349pub use fixed::subscriptions::FixedSubscriptionHandler;
350// Legacy exports for backward compatibility
351pub use fixed::databases::FixedDatabaseHandler as FixedDatabasesHandler;
352pub use fixed::subscriptions::FixedSubscriptionHandler as FixedSubscriptionsHandler;
353
354// Flexible plan handlers (pay-as-you-go)
355pub use flexible::databases::DatabaseHandler;
356pub use flexible::subscriptions::SubscriptionHandler;
357// Legacy exports for backward compatibility
358pub use flexible::databases::DatabaseHandler as DatabasesHandler;
359pub use flexible::subscriptions::SubscriptionHandler as SubscriptionsHandler;
360
361pub use cost_report::CostReportHandler;
362pub use cost_report::{CostReportCreateRequest, CostReportFormat, SubscriptionType, Tag};
363pub use tasks::TasksHandler as TaskHandler;
364pub use users::UsersHandler as UserHandler;