SAL Kubernetes (sal-kubernetes)
Kubernetes cluster management and operations for the System Abstraction Layer (SAL).
Installation
Add this to your Cargo.toml:
[dependencies]
sal-kubernetes = "0.1.0"
⚠️ IMPORTANT SECURITY NOTICE
This package includes destructive operations that can permanently delete Kubernetes resources!
- The delete(pattern)function uses PCRE regex patterns to bulk delete resources
- Always test patterns in a safe environment first
- Use specific patterns to avoid accidental deletion of critical resources
- Consider the impact on dependent resources before deletion
- No confirmation prompts - deletions are immediate and irreversible
Overview
This package provides a high-level interface for managing Kubernetes clusters using the kube-rs SDK. It focuses on namespace-scoped operations through the KubernetesManager factory pattern.
Production Safety Features
- Configurable Timeouts: All operations have configurable timeouts to prevent hanging
- Exponential Backoff Retry: Automatic retry logic for transient failures
- Rate Limiting: Built-in rate limiting to prevent API overload
- Comprehensive Error Handling: Detailed error types and proper error propagation
- Structured Logging: Production-ready logging for monitoring and debugging
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 KubernetesManagerinstance 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 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
// 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:
use sal_kubernetes::KubernetesManager;
use std::collections::HashMap;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    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
use sal_kubernetes::KubernetesManager;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 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(())
}
Rhai Scripting
// Create Kubernetes manager for namespace
let km = kubernetes_manager_new("default");
// 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");
namespace_create(km, "my-namespace");
delete(km, "test-.*");
Dependencies
- kube: Kubernetes client library
- k8s-openapi: Kubernetes API types
- tokio: Async runtime
- regex: Pattern matching for resource deletion
- rhai: Scripting integration (optional)
Configuration
Kubernetes Authentication
The package uses the standard Kubernetes configuration methods:
- In-cluster configuration (when running in a pod)
- Kubeconfig file (~/.kube/configorKUBECONFIGenvironment variable)
- Service account tokens
Production Safety Configuration
use sal_kubernetes::{KubernetesManager, KubernetesConfig};
use std::time::Duration;
// Create with custom configuration
let config = KubernetesConfig::new()
    .with_timeout(Duration::from_secs(60))
    .with_retries(5, Duration::from_secs(1), Duration::from_secs(30))
    .with_rate_limit(20, 50);
let km = KubernetesManager::with_config("my-namespace", config).await?;
Pre-configured Profiles
// High-throughput environment
let config = KubernetesConfig::high_throughput();
// Low-latency environment
let config = KubernetesConfig::low_latency();
// Development/testing
let config = KubernetesConfig::development();
Error Handling
All operations return Result<T, KubernetesError> with comprehensive error types for different failure scenarios including API errors, configuration issues, and permission problems.
API Reference
KubernetesManager
The main interface for Kubernetes operations. Each instance is scoped to a single namespace.
Constructor
- 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
- services_list()- List all services in the namespace
- deployments_list()- List all deployments in the namespace
- configmaps_list()- List all configmaps in the namespace
- secrets_list()- List all secrets in the namespace
Resource Management
- pod_get(name)- Get a specific pod by name
- service_get(name)- Get a specific service by name
- deployment_get(name)- Get a specific deployment by name
- 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
- delete(pattern)- Delete all resources matching a PCRE pattern
Namespace Operations
- namespace_create(name)- Create a namespace (idempotent)
- namespace_exists(name)- Check if a namespace exists
- namespaces_list()- List all namespaces (cluster-wide)
Utility Functions
- resource_counts()- Get counts of all resource types in the namespace
- namespace()- Get the namespace this manager operates on
Rhai Functions
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
- 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/clusters/ directory contains comprehensive examples:
Rust Examples
Run with: cargo run --example <name> --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/<script>.rhai
- postgres.rhai- PostgreSQL cluster deployment script
- redis.rhai- Redis cluster deployment script
Real-World Examples
PostgreSQL Database
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());
km.deploy_application("postgres", "postgres:15", 1, 5432, Some(labels), Some(env_vars)).await?;
Redis Cache
let mut env_vars = HashMap::new();
env_vars.insert("REDIS_PASSWORD".to_string(), "redispassword".to_string());
env_vars.insert("REDIS_MAXMEMORY".to_string(), "256mb".to_string());
km.deploy_application("redis", "redis:7-alpine", 3, 6379, None, Some(env_vars)).await?;
Testing
Test Coverage
The module includes comprehensive test coverage:
- Unit Tests: Core functionality without cluster dependency
- Integration Tests: Real Kubernetes cluster operations
- Environment Variables Tests: Complete env var functionality testing
- Edge Cases Tests: Error handling and boundary conditions
- Rhai Integration Tests: Scripting environment testing
- Production Readiness Tests: Concurrent operations and error handling
Running Tests
# Unit tests (no cluster required)
cargo test --package sal-kubernetes
# Integration tests (requires cluster)
KUBERNETES_TEST_ENABLED=1 cargo test --package sal-kubernetes
# Rhai integration tests
KUBERNETES_TEST_ENABLED=1 cargo test --package sal-kubernetes --features rhai
# Run specific test suites
cargo test --package sal-kubernetes deployment_env_vars_test
cargo test --package sal-kubernetes edge_cases_test
# Rhai environment variables test
KUBERNETES_TEST_ENABLED=1 ./target/debug/herodo kubernetes/tests/rhai/env_vars_test.rhai
Test Requirements
- Kubernetes Cluster: Integration tests require a running Kubernetes cluster
- Environment Variable: Set KUBERNETES_TEST_ENABLED=1to enable integration tests
- Permissions: Tests require permissions to create/delete resources in the defaultnamespace
Production Considerations
Security
- Always use specific PCRE patterns to avoid accidental deletion of important resources
- Test deletion patterns in a safe environment first
- Ensure proper RBAC permissions are configured
- Be cautious with cluster-wide operations like namespace listing
- Use Kubernetes secrets for sensitive environment variables instead of plain text
Performance & Scalability
- Consider adding resource limits (CPU/memory) for production deployments
- Use persistent volumes for stateful applications
- Configure readiness and liveness probes for health checks
- Implement proper monitoring and logging labels
Environment Variables Best Practices
- Use Kubernetes secrets for sensitive data (passwords, API keys)
- Validate environment variable values before deployment
- Use consistent naming conventions (e.g., DATABASE_URL,API_KEY)
- Document required vs optional environment variables
Example: Production-Ready Deployment
// Production labels for monitoring and management
let mut labels = HashMap::new();
labels.insert("app".to_string(), "web-api".to_string());
labels.insert("version".to_string(), "v1.2.3".to_string());
labels.insert("environment".to_string(), "production".to_string());
labels.insert("team".to_string(), "backend".to_string());
// Non-sensitive environment variables
let mut env_vars = HashMap::new();
env_vars.insert("NODE_ENV".to_string(), "production".to_string());
env_vars.insert("LOG_LEVEL".to_string(), "info".to_string());
env_vars.insert("PORT".to_string(), "3000".to_string());
// Note: Use Kubernetes secrets for DATABASE_URL, API_KEY, etc.
km.deploy_application("web-api", "myapp:v1.2.3", 3, 3000, Some(labels), Some(env_vars)).await?;