diff --git a/Cargo.toml b/Cargo.toml index 3b3b3b0..be745ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,7 +88,8 @@ urlencoding = "2.1.3" tokio-test = "0.4.4" [dependencies] -thiserror = "2.0.12" # For error handling in the main Error enum +thiserror = "2.0.12" # For error handling in the main Error enum +tokio = { workspace = true } # For async examples # Optional dependencies - users can choose which modules to include sal-git = { path = "git", optional = true } @@ -146,3 +147,19 @@ all = [ "rhai", "service_manager", ] + +# Examples +[[example]] +name = "postgres_cluster" +path = "examples/kubernetes/clusters/postgres.rs" +required-features = ["kubernetes"] + +[[example]] +name = "redis_cluster" +path = "examples/kubernetes/clusters/redis.rs" +required-features = ["kubernetes"] + +[[example]] +name = "generic_cluster" +path = "examples/kubernetes/clusters/generic.rs" +required-features = ["kubernetes"] diff --git a/examples/kubernetes/clusters/generic.rs b/examples/kubernetes/clusters/generic.rs new file mode 100644 index 0000000..9bb341c --- /dev/null +++ b/examples/kubernetes/clusters/generic.rs @@ -0,0 +1,134 @@ +//! Generic Application Deployment Example +//! +//! This example shows how to deploy any containerized application using the +//! KubernetesManager convenience methods. This works for any Docker image. + +use sal_kubernetes::KubernetesManager; +use std::collections::HashMap; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create Kubernetes manager + let km = KubernetesManager::new("default").await?; + + // Clean up any existing resources first + println!("=== Cleaning up existing resources ==="); + let apps_to_clean = ["web-server", "node-app", "mongodb"]; + + for app in &apps_to_clean { + match km.deployment_delete(app).await { + Ok(_) => println!("✓ Deleted existing deployment: {}", app), + Err(_) => println!("✓ No existing deployment to delete: {}", app), + } + + match km.service_delete(app).await { + Ok(_) => println!("✓ Deleted existing service: {}", app), + Err(_) => println!("✓ No existing service to delete: {}", app), + } + } + + // Example 1: Simple web server deployment + println!("\n=== Example 1: Simple Nginx Web Server ==="); + + km.deploy_application("web-server", "nginx:latest", 2, 80, None, None) + .await?; + println!("✅ Nginx web server deployed!"); + + // Example 2: Node.js application with labels + println!("\n=== Example 2: Node.js Application ==="); + + let mut node_labels = HashMap::new(); + node_labels.insert("app".to_string(), "node-app".to_string()); + node_labels.insert("tier".to_string(), "backend".to_string()); + node_labels.insert("environment".to_string(), "production".to_string()); + + // Configure Node.js environment variables + let mut node_env_vars = HashMap::new(); + node_env_vars.insert("NODE_ENV".to_string(), "production".to_string()); + node_env_vars.insert("PORT".to_string(), "3000".to_string()); + node_env_vars.insert("LOG_LEVEL".to_string(), "info".to_string()); + node_env_vars.insert("MAX_CONNECTIONS".to_string(), "1000".to_string()); + + km.deploy_application( + "node-app", // name + "node:18-alpine", // image + 3, // replicas - scale to 3 instances + 3000, // port + Some(node_labels), // labels + Some(node_env_vars), // environment variables + ) + .await?; + + println!("✅ Node.js application deployed!"); + + // Example 3: Database deployment (any database) + println!("\n=== Example 3: MongoDB Database ==="); + + let mut mongo_labels = HashMap::new(); + mongo_labels.insert("app".to_string(), "mongodb".to_string()); + mongo_labels.insert("type".to_string(), "database".to_string()); + mongo_labels.insert("engine".to_string(), "mongodb".to_string()); + + // Configure MongoDB environment variables + let mut mongo_env_vars = HashMap::new(); + mongo_env_vars.insert( + "MONGO_INITDB_ROOT_USERNAME".to_string(), + "admin".to_string(), + ); + mongo_env_vars.insert( + "MONGO_INITDB_ROOT_PASSWORD".to_string(), + "mongopassword".to_string(), + ); + mongo_env_vars.insert("MONGO_INITDB_DATABASE".to_string(), "myapp".to_string()); + + km.deploy_application( + "mongodb", // name + "mongo:6.0", // image + 1, // replicas - single instance for simplicity + 27017, // port + Some(mongo_labels), // labels + Some(mongo_env_vars), // environment variables + ) + .await?; + + println!("✅ MongoDB deployed!"); + + // Check status of all deployments + println!("\n=== Checking Deployment Status ==="); + + let deployments = km.deployments_list().await?; + + for deployment in &deployments { + if let Some(name) = &deployment.metadata.name { + let total_replicas = deployment + .spec + .as_ref() + .and_then(|s| s.replicas) + .unwrap_or(0); + let ready_replicas = deployment + .status + .as_ref() + .and_then(|s| s.ready_replicas) + .unwrap_or(0); + + println!( + "{}: {}/{} replicas ready", + name, ready_replicas, total_replicas + ); + } + } + + println!("\n🎉 All deployments completed!"); + println!("\n💡 Key Points:"); + println!(" • Any Docker image can be deployed using this simple interface"); + println!(" • Use labels to organize and identify your applications"); + println!( + " • The same method works for databases, web servers, APIs, and any containerized app" + ); + println!(" • For advanced configuration, use the individual KubernetesManager methods"); + println!( + " • Environment variables and resource limits can be added via direct Kubernetes API" + ); + + Ok(()) +} diff --git a/examples/kubernetes/clusters/postgres.rhai b/examples/kubernetes/clusters/postgres.rhai new file mode 100644 index 0000000..6d302d4 --- /dev/null +++ b/examples/kubernetes/clusters/postgres.rhai @@ -0,0 +1,79 @@ +//! PostgreSQL Cluster Deployment Example (Rhai) +//! +//! This script shows how to deploy a PostgreSQL cluster using Rhai scripting +//! with the KubernetesManager convenience methods. + +print("=== PostgreSQL Cluster Deployment ==="); + +// Create Kubernetes manager for the database namespace +print("Creating Kubernetes manager for 'database' namespace..."); +let km = kubernetes_manager_new("database"); +print("✓ Kubernetes manager created"); + +// Create the namespace if it doesn't exist +print("Creating namespace 'database' if it doesn't exist..."); +try { + create_namespace(km, "database"); + print("✓ Namespace 'database' created"); +} catch(e) { + if e.to_string().contains("already exists") { + print("✓ Namespace 'database' already exists"); + } else { + print("⚠️ Warning: " + e); + } +} + +// Clean up any existing resources first +print("\nCleaning up any existing PostgreSQL resources..."); +try { + delete_deployment(km, "postgres-cluster"); + print("✓ Deleted existing deployment"); +} catch(e) { + print("✓ No existing deployment to delete"); +} + +try { + delete_service(km, "postgres-cluster"); + print("✓ Deleted existing service"); +} catch(e) { + print("✓ No existing service to delete"); +} + +// Create PostgreSQL cluster using the convenience method +print("\nDeploying PostgreSQL cluster..."); + +try { + // Deploy PostgreSQL using the convenience method + let result = deploy_application(km, "postgres-cluster", "postgres:15", 2, 5432, #{ + "app": "postgres-cluster", + "type": "database", + "engine": "postgresql" + }, #{ + "POSTGRES_DB": "myapp", + "POSTGRES_USER": "postgres", + "POSTGRES_PASSWORD": "secretpassword", + "PGDATA": "/var/lib/postgresql/data/pgdata" + }); + print("✓ " + result); + + print("\n✅ PostgreSQL cluster deployed successfully!"); + + print("\n📋 Connection Information:"); + print(" Host: postgres-cluster.database.svc.cluster.local"); + print(" Port: 5432"); + print(" Database: postgres (default)"); + print(" Username: postgres (default)"); + + print("\n🔧 To connect from another pod:"); + print(" psql -h postgres-cluster.database.svc.cluster.local -U postgres"); + + print("\n💡 Next steps:"); + print(" • Set POSTGRES_PASSWORD environment variable"); + print(" • Configure persistent storage"); + print(" • Set up backup and monitoring"); + +} catch(e) { + print("❌ Failed to deploy PostgreSQL cluster: " + e); +} + +print("\n=== Deployment Complete ==="); diff --git a/examples/kubernetes/clusters/postgres.rs b/examples/kubernetes/clusters/postgres.rs new file mode 100644 index 0000000..b495940 --- /dev/null +++ b/examples/kubernetes/clusters/postgres.rs @@ -0,0 +1,112 @@ +//! PostgreSQL Cluster Deployment Example +//! +//! This example shows how to deploy a PostgreSQL cluster using the +//! KubernetesManager convenience methods. + +use sal_kubernetes::KubernetesManager; +use std::collections::HashMap; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create Kubernetes manager for the database namespace + let km = KubernetesManager::new("database").await?; + + // Create the namespace if it doesn't exist + println!("Creating namespace 'database' if it doesn't exist..."); + match km.namespace_create("database").await { + Ok(_) => println!("✓ Namespace 'database' created"), + Err(e) => { + if e.to_string().contains("already exists") { + println!("✓ Namespace 'database' already exists"); + } else { + return Err(e.into()); + } + } + } + + // Clean up any existing resources first + println!("Cleaning up any existing PostgreSQL resources..."); + match km.deployment_delete("postgres-cluster").await { + Ok(_) => println!("✓ Deleted existing deployment"), + Err(_) => println!("✓ No existing deployment to delete"), + } + + match km.service_delete("postgres-cluster").await { + Ok(_) => println!("✓ Deleted existing service"), + Err(_) => println!("✓ No existing service to delete"), + } + + // Configure PostgreSQL-specific labels + let mut labels = HashMap::new(); + labels.insert("app".to_string(), "postgres-cluster".to_string()); + labels.insert("type".to_string(), "database".to_string()); + labels.insert("engine".to_string(), "postgresql".to_string()); + + // Configure PostgreSQL environment variables + let mut env_vars = HashMap::new(); + env_vars.insert("POSTGRES_DB".to_string(), "myapp".to_string()); + env_vars.insert("POSTGRES_USER".to_string(), "postgres".to_string()); + env_vars.insert( + "POSTGRES_PASSWORD".to_string(), + "secretpassword".to_string(), + ); + env_vars.insert( + "PGDATA".to_string(), + "/var/lib/postgresql/data/pgdata".to_string(), + ); + + // Deploy the PostgreSQL cluster using the convenience method + println!("Deploying PostgreSQL cluster..."); + km.deploy_application( + "postgres-cluster", // name + "postgres:15", // image + 2, // replicas (1 master + 1 replica) + 5432, // port + Some(labels), // labels + Some(env_vars), // environment variables + ) + .await?; + + println!("✅ PostgreSQL cluster deployed successfully!"); + + // Check deployment status + let deployments = km.deployments_list().await?; + let postgres_deployment = deployments + .iter() + .find(|d| d.metadata.name.as_ref() == Some(&"postgres-cluster".to_string())); + + if let Some(deployment) = postgres_deployment { + let total_replicas = deployment + .spec + .as_ref() + .and_then(|s| s.replicas) + .unwrap_or(0); + let ready_replicas = deployment + .status + .as_ref() + .and_then(|s| s.ready_replicas) + .unwrap_or(0); + + println!( + "Deployment status: {}/{} replicas ready", + ready_replicas, total_replicas + ); + } + + println!("\n📋 Connection Information:"); + println!(" Host: postgres-cluster.database.svc.cluster.local"); + println!(" Port: 5432"); + println!(" Database: postgres (default)"); + println!(" Username: postgres (default)"); + println!(" Password: Set POSTGRES_PASSWORD environment variable"); + + println!("\n🔧 To connect from another pod:"); + println!(" psql -h postgres-cluster.database.svc.cluster.local -U postgres"); + + println!("\n💡 Next steps:"); + println!(" • Set environment variables for database credentials"); + println!(" • Add persistent volume claims for data storage"); + println!(" • Configure backup and monitoring"); + + Ok(()) +} diff --git a/examples/kubernetes/clusters/redis.rhai b/examples/kubernetes/clusters/redis.rhai new file mode 100644 index 0000000..6e75f2d --- /dev/null +++ b/examples/kubernetes/clusters/redis.rhai @@ -0,0 +1,79 @@ +//! Redis Cluster Deployment Example (Rhai) +//! +//! This script shows how to deploy a Redis cluster using Rhai scripting +//! with the KubernetesManager convenience methods. + +print("=== Redis Cluster Deployment ==="); + +// Create Kubernetes manager for the cache namespace +print("Creating Kubernetes manager for 'cache' namespace..."); +let km = kubernetes_manager_new("cache"); +print("✓ Kubernetes manager created"); + +// Create the namespace if it doesn't exist +print("Creating namespace 'cache' if it doesn't exist..."); +try { + create_namespace(km, "cache"); + print("✓ Namespace 'cache' created"); +} catch(e) { + if e.to_string().contains("already exists") { + print("✓ Namespace 'cache' already exists"); + } else { + print("⚠️ Warning: " + e); + } +} + +// Clean up any existing resources first +print("\nCleaning up any existing Redis resources..."); +try { + delete_deployment(km, "redis-cluster"); + print("✓ Deleted existing deployment"); +} catch(e) { + print("✓ No existing deployment to delete"); +} + +try { + delete_service(km, "redis-cluster"); + print("✓ Deleted existing service"); +} catch(e) { + print("✓ No existing service to delete"); +} + +// Create Redis cluster using the convenience method +print("\nDeploying Redis cluster..."); + +try { + // Deploy Redis using the convenience method + let result = deploy_application(km, "redis-cluster", "redis:7-alpine", 3, 6379, #{ + "app": "redis-cluster", + "type": "cache", + "engine": "redis" + }, #{ + "REDIS_PASSWORD": "redispassword", + "REDIS_PORT": "6379", + "REDIS_DATABASES": "16", + "REDIS_MAXMEMORY": "256mb", + "REDIS_MAXMEMORY_POLICY": "allkeys-lru" + }); + print("✓ " + result); + + print("\n✅ Redis cluster deployed successfully!"); + + print("\n📋 Connection Information:"); + print(" Host: redis-cluster.cache.svc.cluster.local"); + print(" Port: 6379"); + + print("\n🔧 To connect from another pod:"); + print(" redis-cli -h redis-cluster.cache.svc.cluster.local"); + + print("\n💡 Next steps:"); + print(" • Configure Redis authentication"); + print(" • Set up Redis clustering configuration"); + print(" • Add persistent storage"); + print(" • Configure memory policies"); + +} catch(e) { + print("❌ Failed to deploy Redis cluster: " + e); +} + +print("\n=== Deployment Complete ==="); diff --git a/examples/kubernetes/clusters/redis.rs b/examples/kubernetes/clusters/redis.rs new file mode 100644 index 0000000..16b9fb7 --- /dev/null +++ b/examples/kubernetes/clusters/redis.rs @@ -0,0 +1,109 @@ +//! Redis Cluster Deployment Example +//! +//! This example shows how to deploy a Redis cluster using the +//! KubernetesManager convenience methods. + +use sal_kubernetes::KubernetesManager; +use std::collections::HashMap; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Create Kubernetes manager for the cache namespace + let km = KubernetesManager::new("cache").await?; + + // Create the namespace if it doesn't exist + println!("Creating namespace 'cache' if it doesn't exist..."); + match km.namespace_create("cache").await { + Ok(_) => println!("✓ Namespace 'cache' created"), + Err(e) => { + if e.to_string().contains("already exists") { + println!("✓ Namespace 'cache' already exists"); + } else { + return Err(e.into()); + } + } + } + + // Clean up any existing resources first + println!("Cleaning up any existing Redis resources..."); + match km.deployment_delete("redis-cluster").await { + Ok(_) => println!("✓ Deleted existing deployment"), + Err(_) => println!("✓ No existing deployment to delete"), + } + + match km.service_delete("redis-cluster").await { + Ok(_) => println!("✓ Deleted existing service"), + Err(_) => println!("✓ No existing service to delete"), + } + + // Configure Redis-specific labels + let mut labels = HashMap::new(); + labels.insert("app".to_string(), "redis-cluster".to_string()); + labels.insert("type".to_string(), "cache".to_string()); + labels.insert("engine".to_string(), "redis".to_string()); + + // Configure Redis environment variables + let mut env_vars = HashMap::new(); + env_vars.insert("REDIS_PASSWORD".to_string(), "redispassword".to_string()); + env_vars.insert("REDIS_PORT".to_string(), "6379".to_string()); + env_vars.insert("REDIS_DATABASES".to_string(), "16".to_string()); + env_vars.insert("REDIS_MAXMEMORY".to_string(), "256mb".to_string()); + env_vars.insert( + "REDIS_MAXMEMORY_POLICY".to_string(), + "allkeys-lru".to_string(), + ); + + // Deploy the Redis cluster using the convenience method + println!("Deploying Redis cluster..."); + km.deploy_application( + "redis-cluster", // name + "redis:7-alpine", // image + 3, // replicas (Redis cluster nodes) + 6379, // port + Some(labels), // labels + Some(env_vars), // environment variables + ) + .await?; + + println!("✅ Redis cluster deployed successfully!"); + + // Check deployment status + let deployments = km.deployments_list().await?; + let redis_deployment = deployments + .iter() + .find(|d| d.metadata.name.as_ref() == Some(&"redis-cluster".to_string())); + + if let Some(deployment) = redis_deployment { + let total_replicas = deployment + .spec + .as_ref() + .and_then(|s| s.replicas) + .unwrap_or(0); + let ready_replicas = deployment + .status + .as_ref() + .and_then(|s| s.ready_replicas) + .unwrap_or(0); + + println!( + "Deployment status: {}/{} replicas ready", + ready_replicas, total_replicas + ); + } + + println!("\n📋 Connection Information:"); + println!(" Host: redis-cluster.cache.svc.cluster.local"); + println!(" Port: 6379"); + println!(" Password: Configure REDIS_PASSWORD environment variable"); + + println!("\n🔧 To connect from another pod:"); + println!(" redis-cli -h redis-cluster.cache.svc.cluster.local"); + + println!("\n💡 Next steps:"); + println!(" • Configure Redis authentication with environment variables"); + println!(" • Set up Redis clustering configuration"); + println!(" • Add persistent volume claims for data persistence"); + println!(" • Configure memory limits and eviction policies"); + + Ok(()) +} diff --git a/kubernetes/Cargo.toml b/kubernetes/Cargo.toml index e2ce593..b07c347 100644 --- a/kubernetes/Cargo.toml +++ b/kubernetes/Cargo.toml @@ -39,6 +39,7 @@ log = "0.4" # Rhai scripting support (optional) rhai = { version = "1.12.0", features = ["sync"], optional = true } +once_cell = "1.20.2" # UUID for resource identification uuid = { version = "1.16.0", features = ["v4"] } diff --git a/kubernetes/README.md b/kubernetes/README.md index 8a6c135..d78b704 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -35,15 +35,96 @@ This package provides a high-level interface for managing Kubernetes clusters us ## Features +- **Application Deployment**: Deploy complete applications with a single method call +- **Environment Variables & Labels**: Configure containers with environment variables and Kubernetes labels +- **Resource Lifecycle Management**: Automatic cleanup and replacement of existing resources - **Namespace-scoped Management**: Each `KubernetesManager` instance operates on a single namespace - **Pod Management**: List, create, and manage pods - **Pattern-based Deletion**: Delete resources using PCRE pattern matching - **Namespace Operations**: Create and manage namespaces (idempotent operations) - **Resource Management**: Support for pods, services, deployments, configmaps, secrets, and more -- **Rhai Integration**: Full scripting support through Rhai wrappers +- **Rhai Integration**: Full scripting support through Rhai wrappers with environment variables + +## Core Concepts + +### Labels vs Environment Variables + +Understanding the difference between labels and environment variables is crucial for effective Kubernetes deployments: + +#### **Labels** (Kubernetes Metadata) + +- **Purpose**: Organize, select, and manage Kubernetes resources +- **Scope**: Kubernetes cluster management and resource organization +- **Visibility**: Used by Kubernetes controllers, selectors, and monitoring systems +- **Examples**: `app=my-app`, `tier=backend`, `environment=production`, `version=v1.2.3` +- **Use Cases**: Resource grouping, service discovery, monitoring labels, deployment strategies + +#### **Environment Variables** (Container Configuration) + +- **Purpose**: Configure application runtime behavior and settings +- **Scope**: Inside container processes - available to your application code +- **Visibility**: Accessible via `process.env`, `os.environ`, etc. in your application +- **Examples**: `NODE_ENV=production`, `DATABASE_URL=postgres://...`, `API_KEY=secret` +- **Use Cases**: Database connections, API keys, feature flags, runtime configuration + +#### **Example: Complete Application Configuration** + +```rust +// Labels: For Kubernetes resource management +let mut labels = HashMap::new(); +labels.insert("app".to_string(), "web-api".to_string()); // Service discovery +labels.insert("tier".to_string(), "backend".to_string()); // Architecture layer +labels.insert("environment".to_string(), "production".to_string()); // Deployment stage +labels.insert("version".to_string(), "v2.1.0".to_string()); // Release version + +// Environment Variables: For application configuration +let mut env_vars = HashMap::new(); +env_vars.insert("NODE_ENV".to_string(), "production".to_string()); // Runtime mode +env_vars.insert("DATABASE_URL".to_string(), "postgres://db:5432/app".to_string()); // DB connection +env_vars.insert("REDIS_URL".to_string(), "redis://cache:6379".to_string()); // Cache connection +env_vars.insert("LOG_LEVEL".to_string(), "info".to_string()); // Logging config +``` ## Usage +### Application Deployment (Recommended) + +Deploy complete applications with labels and environment variables: + +```rust +use sal_kubernetes::KubernetesManager; +use std::collections::HashMap; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let km = KubernetesManager::new("default").await?; + + // Configure labels for Kubernetes resource organization + let mut labels = HashMap::new(); + labels.insert("app".to_string(), "my-app".to_string()); + labels.insert("tier".to_string(), "backend".to_string()); + + // Configure environment variables for the container + let mut env_vars = HashMap::new(); + env_vars.insert("NODE_ENV".to_string(), "production".to_string()); + env_vars.insert("DATABASE_URL".to_string(), "postgres://db:5432/myapp".to_string()); + env_vars.insert("API_KEY".to_string(), "secret-api-key".to_string()); + + // Deploy application with deployment + service + km.deploy_application( + "my-app", // name + "node:18-alpine", // image + 3, // replicas + 3000, // port + Some(labels), // Kubernetes labels + Some(env_vars), // container environment variables + ).await?; + + println!("✅ Application deployed successfully!"); + Ok(()) +} +``` + ### Basic Operations ```rust @@ -53,17 +134,17 @@ use sal_kubernetes::KubernetesManager; async fn main() -> Result<(), Box> { // Create a manager for the "default" namespace let km = KubernetesManager::new("default").await?; - + // List all pods in the namespace let pods = km.pods_list().await?; println!("Found {} pods", pods.len()); - + // Create a namespace (no error if it already exists) km.namespace_create("my-namespace").await?; - + // Delete resources matching a pattern km.delete("test-.*").await?; - + Ok(()) } ``` @@ -74,14 +155,24 @@ async fn main() -> Result<(), Box> { // Create Kubernetes manager for namespace let km = kubernetes_manager_new("default"); -// List pods +// Deploy application with labels and environment variables +deploy_application(km, "my-app", "node:18-alpine", 3, 3000, #{ + "app": "my-app", + "tier": "backend", + "environment": "production" +}, #{ + "NODE_ENV": "production", + "DATABASE_URL": "postgres://db:5432/myapp", + "API_KEY": "secret-api-key" +}); + +print("✅ Application deployed!"); + +// Basic operations let pods = pods_list(km); print("Found " + pods.len() + " pods"); -// Create namespace -namespace_create(km, "my-app"); - -// Delete test resources +namespace_create(km, "my-namespace"); delete(km, "test-.*"); ``` @@ -98,6 +189,7 @@ delete(km, "test-.*"); ### Kubernetes Authentication The package uses the standard Kubernetes configuration methods: + - In-cluster configuration (when running in a pod) - Kubeconfig file (`~/.kube/config` or `KUBECONFIG` environment variable) - Service account tokens @@ -144,6 +236,18 @@ The main interface for Kubernetes operations. Each instance is scoped to a singl - `KubernetesManager::new(namespace)` - Create a manager for the specified namespace +#### Application Deployment + +- `deploy_application(name, image, replicas, port, labels, env_vars)` - Deploy complete application with deployment and service +- `deployment_create(name, image, replicas, labels, env_vars)` - Create deployment with environment variables and labels + +#### Resource Creation + +- `pod_create(name, image, labels, env_vars)` - Create pod with environment variables and labels +- `service_create(name, selector, port, target_port)` - Create service with port mapping +- `configmap_create(name, data)` - Create configmap with data +- `secret_create(name, data, secret_type)` - Create secret with data and optional type + #### Resource Listing - `pods_list()` - List all pods in the namespace @@ -160,6 +264,8 @@ The main interface for Kubernetes operations. Each instance is scoped to a singl - `pod_delete(name)` - Delete a specific pod by name - `service_delete(name)` - Delete a specific service by name - `deployment_delete(name)` - Delete a specific deployment by name +- `configmap_delete(name)` - Delete a specific configmap by name +- `secret_delete(name)` - Delete a specific secret by name #### Pattern-based Operations @@ -180,32 +286,93 @@ The main interface for Kubernetes operations. Each instance is scoped to a singl When using the Rhai integration, the following functions are available: +**Manager Creation & Application Deployment:** + - `kubernetes_manager_new(namespace)` - Create a KubernetesManager +- `deploy_application(km, name, image, replicas, port, labels, env_vars)` - Deploy application with environment variables + +**Resource Listing:** + - `pods_list(km)` - List pods - `services_list(km)` - List services - `deployments_list(km)` - List deployments +- `configmaps_list(km)` - List configmaps +- `secrets_list(km)` - List secrets - `namespaces_list(km)` - List all namespaces -- `delete(km, pattern)` - Delete resources matching pattern -- `namespace_create(km, name)` - Create namespace -- `namespace_exists(km, name)` - Check namespace existence - `resource_counts(km)` - Get resource counts + +**Resource Operations:** + +- `delete(km, pattern)` - Delete resources matching pattern - `pod_delete(km, name)` - Delete specific pod - `service_delete(km, name)` - Delete specific service - `deployment_delete(km, name)` - Delete specific deployment +- `configmap_delete(km, name)` - Delete specific configmap +- `secret_delete(km, name)` - Delete specific secret + +**Namespace Functions:** + +- `namespace_create(km, name)` - Create namespace +- `namespace_exists(km, name)` - Check namespace existence +- `namespace_delete(km, name)` - Delete namespace - `namespace(km)` - Get manager's namespace ## Examples -The `examples/kubernetes/` directory contains comprehensive examples: +The `examples/kubernetes/clusters/` directory contains comprehensive examples: -- `basic_operations.rhai` - Basic listing and counting operations -- `namespace_management.rhai` - Creating and managing namespaces -- `pattern_deletion.rhai` - Using PCRE patterns for bulk deletion -- `multi_namespace_operations.rhai` - Working across multiple namespaces +### Rust Examples + +Run with: `cargo run --example --features kubernetes` + +- `postgres` - PostgreSQL database deployment with environment variables +- `redis` - Redis cache deployment with configuration +- `generic` - Multiple application deployments (nginx, node.js, mongodb) + +### Rhai Examples + +Run with: `./target/debug/herodo examples/kubernetes/clusters/