Skip to main content

10_provider_switching/
10_provider_switching.rs

1//! Provider Switching
2//!
3//! This example demonstrates:
4//! - Using service.with_provider() to dynamically switch providers
5//! - Same service, different cloud backends
6//! - Provider-specific feature handling
7//!
8//! Scenario: Operations team managing resources across AWS and GCP.
9//!
10//! Run with: `cargo run --example 10_provider_switching`
11
12use std::sync::Arc;
13use tokio::sync::RwLock;
14use wami::arn::{TenantPath, WamiArn};
15use wami::context::WamiContext;
16use wami::service::UserService;
17use wami::store::memory::InMemoryWamiStore;
18use wami::wami::identity::user::requests::{CreateUserRequest, ListUsersRequest};
19
20#[tokio::main]
21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22    println!("=== Provider Switching (Multi-Context) ===\n");
23
24    let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
25
26    // Create a WamiContext for operations
27    let context = WamiContext::builder()
28        .instance_id("123456789012")
29        .tenant_path(TenantPath::single(0))
30        .caller_arn(
31            WamiArn::builder()
32                .service(wami::arn::Service::Iam)
33                .tenant_path(TenantPath::single(0))
34                .wami_instance("123456789012")
35                .resource("user", "admin")
36                .build()?,
37        )
38        .is_root(false)
39        .build()?;
40
41    // === CREATE SERVICE ===
42    println!("Step 1: Creating service...\n");
43
44    let user_service = UserService::new(store.clone());
45
46    println!("✓ Service created");
47
48    // === CREATE USER WITH CONTEXT ===
49    println!("\nStep 2: Creating user with context...\n");
50
51    let alice_req = CreateUserRequest {
52        user_name: "alice".to_string(),
53        path: Some("/".to_string()),
54        permissions_boundary: None,
55        tags: None,
56    };
57
58    let alice = user_service.create_user(&context, alice_req).await?;
59    println!("✓ Created alice:");
60    println!("  - ARN: {}", alice.arn);
61    println!("  - WAMI ARN: {}", alice.wami_arn);
62
63    // === CREATE ANOTHER USER ===
64    println!("\nStep 3: Creating another user...\n");
65
66    let bob_req = CreateUserRequest {
67        user_name: "bob".to_string(),
68        path: Some("/".to_string()),
69        permissions_boundary: None,
70        tags: None,
71    };
72
73    let bob = user_service.create_user(&context, bob_req).await?;
74    println!("✓ Created bob:");
75    println!("  - ARN: {}", bob.arn);
76    println!("  - WAMI ARN: {}", bob.wami_arn);
77
78    // === LIST ALL USERS ===
79    println!("\n\nStep 4: Listing all users...\n");
80
81    let (users, _, _) = user_service
82        .list_users(
83            &context,
84            ListUsersRequest {
85                path_prefix: None,
86                pagination: None,
87            },
88        )
89        .await?;
90    println!("✓ Found {} users:", users.len());
91    for user in &users {
92        println!("  - {} → {}", user.user_name, user.arn);
93    }
94
95    // === DEMONSTRATE USE CASES ===
96    println!("\n\nStep 5: Understanding WAMI architecture...\n");
97
98    println!("WAMI enables:");
99    println!("- Multi-cloud deployments with unified ARN format");
100    println!("- Provider-agnostic operations through WamiContext");
101    println!("- Cloud-agnostic CI/CD pipelines");
102    println!("- Consistent resource identification across providers");
103    println!("- Flexible multi-tenant and multi-cloud patterns");
104
105    println!("\nExample usage patterns:");
106    println!("```rust");
107    println!("// Create context with instance and tenant information");
108    println!("let context = WamiContext::builder()");
109    println!("    .instance_id(\"123456789012\")");
110    println!("    .tenant_path(TenantPath::single(\"root\"))");
111    println!("    .caller_arn(...)");
112    println!("    .build()?;");
113    println!();
114    println!("// Use context for all operations");
115    println!("let user = service.create_user(&context, request).await?;");
116    println!("```");
117
118    println!("\n✅ Example completed successfully!");
119    println!("Key takeaways:");
120    println!("- Services use WamiContext instead of providers");
121    println!("- Context contains instance, tenant, and caller information");
122    println!("- All operations use WAMI ARNs for consistent identification");
123    println!("- Provider-specific ARNs can be generated when needed");
124
125    Ok(())
126}