# Crossplane Provider for Proxmox A custom Crossplane provider that enables provisioning and management of Proxmox VE resources through Kubernetes. ## Features - **Virtual Machine Management**: Create, update, delete VMs - **Storage Management**: Manage storage pools and volumes - **Network Management**: Configure network bridges and interfaces - **Multi-Site Support**: Manage multiple Proxmox clusters - **Status Reporting**: Real-time VM status and IP addresses - **Reconciliation**: Automatic drift detection and correction - **Retry Logic**: Automatic retry for transient failures - **Error Handling**: Comprehensive error handling and reporting ## Architecture ``` crossplane-provider-proxmox/ ├── apis/ # CRD API definitions │ └── v1alpha1/ # API version ├── pkg/ # Provider implementation │ ├── controller/ # Crossplane controllers │ ├── proxmox/ # Proxmox API client │ └── managed/ # Managed resource types ├── config/ # Deployment manifests │ └── crd/ # CRD definitions └── examples/ # Usage examples ``` ## Installation ### Prerequisites - Kubernetes cluster with Crossplane installed - Proxmox VE cluster with API access - Go 1.21+ for building ### Build and Install ```bash # Build the provider make build # Install CRDs kubectl apply -f config/crd/bases/ # Deploy the provider kubectl apply -f config/provider.yaml # Create ProviderConfig kubectl apply -f examples/provider-config.yaml ``` ## Configuration ### Module Path **IMPORTANT**: Before building, update the module path in `go.mod`: ```go module github.com/sankofa/crossplane-provider-proxmox ``` ### Provider Configuration ```yaml apiVersion: proxmox.sankofa.nexus/v1alpha1 kind: ProviderConfig metadata: name: proxmox-provider-config spec: credentials: source: Secret secretRef: name: proxmox-credentials namespace: crossplane-system key: credentials.json sites: - name: us-sfvalley endpoint: https://ml110-01.sankofa.nexus:8006 node: ML110-01 - name: eu-west-1 endpoint: https://r630-01.sankofa.nexus:8006 node: R630-01 ``` ### Create a Virtual Machine ```yaml apiVersion: proxmox.sankofa.nexus/v1alpha1 kind: ProxmoxVM metadata: name: web-server-01 spec: forProvider: node: pve1 name: web-server-01 cpu: 4 memory: 8Gi disk: 100Gi storage: local-lvm network: vmbr0 image: ubuntu-22.04-cloud site: us-sfvalley providerConfigRef: name: proxmox-provider-config ``` ## API Reference ### ProxmoxVM Manages a Proxmox virtual machine. **Spec:** - `node`: Proxmox node to deploy on (required) - `name`: VM name (required, see validation rules below) - `cpu`: Number of CPU cores (required, min: 1, max: 1024, default: 2) - `memory`: Memory size (required, see validation rules below) - `disk`: Disk size (required, see validation rules below) - `storage`: Storage pool name (default: "local-lvm") - `network`: Network bridge (default: "vmbr0", see validation rules below) - `image`: OS template/image (required, see validation rules below) - `site`: Site identifier (required, must match ProviderConfig) - `userData`: Optional cloud-init user data in YAML format **Status:** - `vmId`: Proxmox VM ID - `state`: VM state (running, stopped, etc.) - `ipAddress`: VM IP address - `conditions`: Resource conditions ### Validation Rules The provider includes comprehensive input validation: #### VM Name - **Length**: 1-100 characters - **Characters**: Alphanumeric, hyphen, underscore, dot, space - **Restrictions**: Cannot start or end with spaces - **Example**: `"web-server-01"`, `"vm.001"`, `"my vm"` #### Memory - **Format**: Supports `Gi`, `Mi`, `Ki`, `G`, `M`, `K` or plain numbers (assumed MB) - **Range**: 128 MB - 2 TB - **Case-insensitive**: `"4Gi"`, `"4gi"`, `"4GI"` all work - **Examples**: `"4Gi"`, `"8192Mi"`, `"4096"` #### Disk - **Format**: Supports `Ti`, `Gi`, `Mi`, `T`, `G`, `M` or plain numbers (assumed GB) - **Range**: 1 GB - 100 TB - **Case-insensitive**: `"50Gi"`, `"50gi"`, `"50GI"` all work - **Examples**: `"50Gi"`, `"1Ti"`, `"100"` #### CPU - **Range**: 1-1024 cores - **Example**: `2`, `4`, `8` #### Network Bridge - **Format**: Alphanumeric, hyphen, underscore - **Validation**: Bridge must exist on the target node (validated before VM creation) - **Example**: `"vmbr0"`, `"custom-bridge"`, `"bridge_01"` #### Image Three formats are supported: 1. **Template VMID**: Numeric VMID (100-999999999) for template cloning - Example: `"100"`, `"1000"` 2. **Volume ID**: `storage:path/to/image` format - Example: `"local:iso/ubuntu-22.04.iso"` 3. **Image Name**: Named image in storage - Example: `"ubuntu-22.04-cloud"` - Maximum length: 255 characters ### Multi-Tenancy The provider supports tenant isolation through tags: - **Tenant ID**: Set via Kubernetes label `tenant-id` or `tenant.sankofa.nexus/id` - **Tag Format**: `tenant_{id}` (underscore separator) - **Filtering**: Use `ListVMs()` with tenant ID filter - **Example**: ```yaml metadata: labels: tenant-id: "customer-123" # Results in Proxmox tag: tenant_customer-123 ``` ## Error Handling and Retry Logic The provider includes comprehensive error handling and automatic retry logic: ### Error Categories - **Network Errors**: Automatically retried with exponential backoff - Connection failures, timeouts, 502/503 errors - **Authentication Errors**: Not retried (requires credential fix) - Invalid credentials, 401/403 errors - **Configuration Errors**: Not retried (requires manual intervention) - Missing ProviderConfig, invalid site configuration - **Quota Errors**: Not retried (requires resource adjustment) - Resource quota exceeded - **API Not Supported**: Not retried - importdisk API not available (falls back to template cloning) ### Retry Configuration - **Max Retries**: 3 (configurable) - **Backoff**: Exponential with jitter - **Max Delay**: 30 seconds - **Retryable Errors**: Network, temporary failures ### Error Reporting Errors are reported via Kubernetes Conditions: - `ValidationFailed`: Input validation errors - `ConfigurationError`: Configuration issues - `NetworkError`: Network connectivity problems - `AuthenticationError`: Authentication failures - `QuotaExceeded`: Resource quota violations - `NodeUnhealthy`: Node health check failures ## Development ### Building ```bash go mod download go build -o bin/provider ./cmd/provider ``` ### Testing #### Unit Tests ```bash # Run all unit tests go test ./pkg/... # Run with coverage go test -cover ./pkg/... go test -coverprofile=coverage.out ./pkg/... go tool cover -html=coverage.out # Run specific package tests go test ./pkg/utils/... go test ./pkg/proxmox/... go test ./pkg/controller/virtualmachine/... ``` #### Integration Tests ```bash # Run integration tests (requires Proxmox test environment) go test -tags=integration ./pkg/controller/virtualmachine/... # Skip integration tests go test -short ./pkg/... ``` See [docs/TESTING.md](docs/TESTING.md) for detailed testing guidelines. ### Running Locally ```bash # Set up local development environment export PROXMOX_ENDPOINT=https://pve1.local:8006 export PROXMOX_USERNAME=root@pam export PROXMOX_PASSWORD=your-password # Run the provider ./bin/provider ``` ## Troubleshooting ### Common Issues #### Validation Errors **VM Name Invalid** ``` Error: VM name contains invalid characters ``` - **Solution**: Ensure VM name only contains alphanumeric, hyphen, underscore, dot, or space characters **Memory/Disk Out of Range** ``` Error: memory 64Mi is below minimum of 128 MB ``` - **Solution**: Increase memory/disk values to meet minimum requirements (128 MB memory, 1 GB disk) **Network Bridge Not Found** ``` Error: network bridge 'vmbr999' does not exist on node 'test-node' ``` - **Solution**: Verify network bridge exists using `pvesh get /nodes/{node}/network` or create the bridge #### Authentication Errors **401 Unauthorized** - **Solution**: Verify credentials in ProviderConfig secret are correct - Check API token format: `PVEAPIToken ${token}` (space, not equals sign) #### Image Import Errors **importdisk API Not Supported** ``` Error: importdisk API is not supported in this Proxmox version ``` - **Solution**: Use template cloning (numeric VMID) or pre-imported images instead - Or upgrade Proxmox to version 6.0+ #### Network Errors **Connection Timeout** - **Solution**: Verify Proxmox API endpoint is accessible - Check firewall rules and network connectivity ### Debugging Enable verbose logging: ```bash # Set log level export LOG_LEVEL=debug # Run provider with debug logging ./bin/provider --log-level=debug ``` Check VM status: ```bash # Get VM details kubectl get proxmoxvm -o yaml # Check conditions kubectl describe proxmoxvm # View controller logs kubectl logs -n crossplane-system -l app=provider-proxmox ``` ## Additional Resources - [Testing Guide](docs/TESTING.md) - Comprehensive testing documentation - [API Examples](examples/) - Usage examples - [Proxmox API Documentation](https://pve.proxmox.com/pve-docs/api-viewer/) ## License Apache 2.0