Skip to content

Commit 73dc611

Browse files
Merge pull request #10 from joshrotenberg/feat/enterprise-api-completeness
feat: achieve 100% Redis Enterprise REST API coverage
2 parents dca6394 + 82b6501 commit 73dc611

File tree

13 files changed

+1745
-174
lines changed

13 files changed

+1745
-174
lines changed

CLAUDE.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -440,13 +440,16 @@ Based on Redis Enterprise REST API v7+ documentation:
440440
- Testing: `wiremock`, `mockall`, `serial_test`
441441
- Auth: `rpassword` for password input
442442

443-
## Current Status (Session Update - 2025-01-23)
443+
## Current Status (Session Update - 2025-01-26)
444444

445445
### Recent Achievements ✅
446-
1. **SSO/SAML Implementation**: Added comprehensive enterprise authentication with 19 commands (PR #91)
447-
2. **CI Optimization**: Fixed 13-minute code coverage runtime, now 3-5 minutes (60-75% improvement)
448-
3. **Dependency Updates**: Updated to Rust 2024 edition and version 1.89
449-
4. **Quality Standards**: 500+ tests passing, full clippy/fmt compliance
446+
1. **100% Database Struct Coverage**: Achieved 155/152 fields (102%) in DatabaseInfo struct with all 152 official API fields plus 3 legacy/computed fields
447+
2. **Complete API Documentation Validation**: Extracted and validated against official Redis Enterprise schema from Docker container
448+
3. **Quality Standards**: 500+ tests passing, full clippy/fmt compliance, all formatting checks passed
449+
4. **Node Struct Coverage**: Previously achieved 100% (33/33 fields)
450+
5. **SSO/SAML Implementation**: Added comprehensive enterprise authentication with 19 commands (PR #91)
451+
6. **CI Optimization**: Fixed 13-minute code coverage runtime, now 3-5 minutes (60-75% improvement)
452+
7. **Dependency Updates**: Updated to Rust 2024 edition and version 1.89
450453

451454
### Current Architecture Health
452455
- **Cloud API**: 95%+ coverage, 12/21 handlers tested, comprehensive endpoint support
@@ -464,8 +467,9 @@ Based on Redis Enterprise REST API v7+ documentation:
464467

465468
**Medium Priority:**
466469
5. **Testing**: Complete test coverage for remaining 15 untested handlers
467-
6. **Documentation**: Update with latest SSO/SAML features
470+
6. **Documentation**: Update with latest SSO/SAML features
468471
7. **Workflow Commands**: Implement multi-step orchestration (issues #82-85)
472+
8. **Docker-wrapper Update**: Upgrade to docker-wrapper 0.8.0 when available
469473

470474
### Next Session Workflow
471475
1. **Setup**: Read CLAUDE.md, sync with main branch, run `cargo test --workspace`

crates/redis-cloud/src/lib.rs

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,203 @@
22
//!
33
//! This module provides a client for interacting with Redis Cloud's REST API,
44
//! enabling subscription management, database operations, and monitoring.
5+
//!
6+
//! # Examples
7+
//!
8+
//! ## Creating a Client
9+
//!
10+
//! ```ignore
11+
//! use redis_cloud::{CloudClient, CloudConfig};
12+
//!
13+
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
14+
//! let config = CloudConfig {
15+
//! api_key: "your-api-key".to_string(),
16+
//! api_secret_key: "your-secret-key".to_string(),
17+
//! api_url: "https://api.redislabs.com/v1".to_string(),
18+
//! };
19+
//!
20+
//! let client = CloudClient::new(config)?;
21+
//! # Ok(())
22+
//! # }
23+
//! ```
24+
//!
25+
//! ## Managing Subscriptions
26+
//!
27+
//! ```ignore
28+
//! use redis_cloud::{CloudClient, CloudSubscriptionHandler, CreateSubscriptionRequest};
29+
//!
30+
//! # async fn example(client: CloudClient) -> Result<(), Box<dyn std::error::Error>> {
31+
//! let handler = CloudSubscriptionHandler::new(client);
32+
//!
33+
//! // List all subscriptions
34+
//! let subscriptions = handler.list().await?;
35+
//! for sub in subscriptions {
36+
//! println!("Subscription: {} ({})", sub.name, sub.id);
37+
//! }
38+
//!
39+
//! // Create a new subscription
40+
//! let request = CreateSubscriptionRequest {
41+
//! name: "production".to_string(),
42+
//! payment_method_id: 123,
43+
//! memory_storage: "ram".to_string(),
44+
//! cloud_provider: vec![/* provider config */],
45+
//! // ... other fields
46+
//! };
47+
//!
48+
//! let new_sub = handler.create(request).await?;
49+
//! println!("Created subscription: {}", new_sub.id);
50+
//! # Ok(())
51+
//! # }
52+
//! ```
53+
//!
54+
//! ## Database Operations
55+
//!
56+
//! ```ignore
57+
//! use redis_cloud::{CloudClient, CloudDatabaseHandler, CreateDatabaseRequest};
58+
//!
59+
//! # async fn example(client: CloudClient) -> Result<(), Box<dyn std::error::Error>> {
60+
//! let handler = CloudDatabaseHandler::new(client);
61+
//! let subscription_id = 12345;
62+
//!
63+
//! // List databases in a subscription
64+
//! let databases = handler.list(subscription_id).await?;
65+
//! for db in databases {
66+
//! println!("Database: {} at {}:{}", db.name, db.public_endpoint, db.port);
67+
//! }
68+
//!
69+
//! // Create a new database
70+
//! let request = CreateDatabaseRequest {
71+
//! name: "cache-db".to_string(),
72+
//! memory_limit_in_gb: 1.0,
73+
//! modules: vec!["RedisJSON".to_string()],
74+
//! data_persistence: "aof-every-1-second".to_string(),
75+
//! replication: true,
76+
//! // ... other fields
77+
//! };
78+
//!
79+
//! let new_db = handler.create(subscription_id, request).await?;
80+
//! println!("Created database: {}", new_db.database_id);
81+
//!
82+
//! // Get database metrics
83+
//! let metrics = handler.get_metrics(subscription_id, new_db.database_id, None, None).await?;
84+
//! println!("Ops/sec: {:?}", metrics);
85+
//! # Ok(())
86+
//! # }
87+
//! ```
88+
//!
89+
//! ## Backup Management
90+
//!
91+
//! ```ignore
92+
//! use redis_cloud::{CloudClient, CloudBackupHandler, CreateBackupRequest};
93+
//!
94+
//! # async fn example(client: CloudClient) -> Result<(), Box<dyn std::error::Error>> {
95+
//! let handler = CloudBackupHandler::new(client);
96+
//! let subscription_id = 12345;
97+
//! let database_id = 67890;
98+
//!
99+
//! // List backups
100+
//! let backups = handler.list(subscription_id, database_id).await?;
101+
//! for backup in backups {
102+
//! println!("Backup: {} ({})", backup.backup_id, backup.status);
103+
//! }
104+
//!
105+
//! // Create a backup
106+
//! let request = CreateBackupRequest {
107+
//! description: Some("Pre-deployment backup".to_string()),
108+
//! };
109+
//!
110+
//! let new_backup = handler.create(subscription_id, database_id, request).await?;
111+
//! println!("Created backup: {}", new_backup.backup_id);
112+
//!
113+
//! // Restore from backup
114+
//! handler.restore(subscription_id, database_id, new_backup.backup_id).await?;
115+
//! println!("Restore initiated");
116+
//! # Ok(())
117+
//! # }
118+
//! ```
119+
//!
120+
//! ## ACL Management
121+
//!
122+
//! ```ignore
123+
//! use redis_cloud::{CloudClient, CloudAclHandler};
124+
//!
125+
//! # async fn example(client: CloudClient) -> Result<(), Box<dyn std::error::Error>> {
126+
//! let handler = CloudAclHandler::new(client);
127+
//! let subscription_id = 12345;
128+
//! let database_id = 67890;
129+
//!
130+
//! // Get database ACLs
131+
//! let acls = handler.get_database_acls(subscription_id, database_id).await?;
132+
//! for acl in acls {
133+
//! println!("ACL User: {}", acl.username);
134+
//! }
135+
//!
136+
//! // List ACL users
137+
//! let users = handler.list_acl_users().await?;
138+
//! for user in users {
139+
//! println!("User: {} - Rules: {:?}", user.name, user.rules);
140+
//! }
141+
//!
142+
//! // List ACL roles
143+
//! let roles = handler.list_acl_roles().await?;
144+
//! for role in roles {
145+
//! println!("Role: {} - Permissions: {:?}", role.name, role.permissions);
146+
//! }
147+
//! # Ok(())
148+
//! # }
149+
//! ```
150+
//!
151+
//! ## VPC Peering
152+
//!
153+
//! ```ignore
154+
//! use redis_cloud::{CloudClient, CloudPeeringHandler, CreatePeeringRequest};
155+
//!
156+
//! # async fn example(client: CloudClient) -> Result<(), Box<dyn std::error::Error>> {
157+
//! let handler = CloudPeeringHandler::new(client);
158+
//! let subscription_id = 12345;
159+
//!
160+
//! // List peerings
161+
//! let peerings = handler.list(subscription_id).await?;
162+
//! for peering in peerings {
163+
//! println!("Peering: {} ({})", peering.peering_id, peering.status);
164+
//! }
165+
//!
166+
//! // Create VPC peering
167+
//! let request = CreatePeeringRequest {
168+
//! aws_account_id: "123456789012".to_string(),
169+
//! vpc_id: "vpc-12345".to_string(),
170+
//! vpc_cidr: "10.0.0.0/16".to_string(),
171+
//! region: "us-east-1".to_string(),
172+
//! };
173+
//!
174+
//! let new_peering = handler.create(subscription_id, request).await?;
175+
//! println!("Created peering: {}", new_peering.peering_id);
176+
//! # Ok(())
177+
//! # }
178+
//! ```
179+
//!
180+
//! ## Cloud Provider Regions
181+
//!
182+
//! ```ignore
183+
//! use redis_cloud::{CloudClient, CloudRegionHandler};
184+
//!
185+
//! # async fn example(client: CloudClient) -> Result<(), Box<dyn std::error::Error>> {
186+
//! let handler = CloudRegionHandler::new(client);
187+
//!
188+
//! // List AWS regions
189+
//! let aws_regions = handler.list("AWS").await?;
190+
//! for region in aws_regions {
191+
//! println!("AWS Region: {} - {}", region.name, region.display_name);
192+
//! }
193+
//!
194+
//! // List GCP regions
195+
//! let gcp_regions = handler.list("GCP").await?;
196+
//! for region in gcp_regions {
197+
//! println!("GCP Region: {} - {}", region.name, region.display_name);
198+
//! }
199+
//! # Ok(())
200+
//! # }
201+
//! ```
5202
6203
pub mod client;
7204
pub mod handlers;

0 commit comments

Comments
 (0)