#!/bin/bash # verify-provider-deployment.sh # Verifies Crossplane provider deployment and configuration set -euo pipefail # Colors GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Configuration NAMESPACE="${NAMESPACE:-crossplane-system}" PROVIDER_NAME="crossplane-provider-proxmox" PROVIDER_CONFIG_NAME="proxmox-provider-config" log() { echo -e "${GREEN}[INFO]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" >&2 } warn() { echo -e "${YELLOW}[WARN]${NC} $1" } info() { echo -e "${BLUE}[INFO]${NC} $1" } check_kubectl() { if ! command -v kubectl &> /dev/null; then error "kubectl is required but not installed" return 1 fi if ! kubectl cluster-info &> /dev/null; then error "Cannot connect to Kubernetes cluster" return 1 fi return 0 } check_crds() { log "Checking CRDs..." local crds=( "proxmoxvms.proxmox.sankofa.nexus" "proxmoxvmscalesets.proxmox.sankofa.nexus" "providerconfigs.proxmox.sankofa.nexus" ) local all_ok=true for crd in "${crds[@]}"; do if kubectl get crd "${crd}" &> /dev/null; then log " ✓ CRD exists: ${crd}" else error " ✗ CRD missing: ${crd}" all_ok=false fi done return $([ "$all_ok" = true ] && echo 0 || echo 1) } check_provider_deployment() { log "Checking provider deployment..." if kubectl get deployment "${PROVIDER_NAME}" -n "${NAMESPACE}" &> /dev/null; then log " ✓ Deployment exists: ${PROVIDER_NAME}" # Check replicas local desired=$(kubectl get deployment "${PROVIDER_NAME}" -n "${NAMESPACE}" -o jsonpath='{.spec.replicas}') local ready=$(kubectl get deployment "${PROVIDER_NAME}" -n "${NAMESPACE}" -o jsonpath='{.status.readyReplicas}') if [ "$desired" = "$ready" ] && [ "$ready" != "0" ]; then log " ✓ Deployment ready: ${ready}/${desired} replicas" else warn " ⚠ Deployment not ready: ${ready}/${desired} replicas" return 1 fi else error " ✗ Deployment missing: ${PROVIDER_NAME}" return 1 fi return 0 } check_provider_pod() { log "Checking provider pod..." local pod=$(kubectl get pod -n "${NAMESPACE}" -l app="${PROVIDER_NAME}" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null) if [ -z "$pod" ]; then error " ✗ No provider pod found" return 1 fi log " ✓ Pod found: ${pod}" # Check pod status local phase=$(kubectl get pod "${pod}" -n "${NAMESPACE}" -o jsonpath='{.status.phase}') if [ "$phase" = "Running" ]; then log " ✓ Pod status: ${phase}" else warn " ⚠ Pod status: ${phase}" return 1 fi # Check for errors in logs local error_count=$(kubectl logs "${pod}" -n "${NAMESPACE}" --tail=50 2>&1 | grep -i "error\|fatal\|panic" | wc -l) if [ "$error_count" -gt 0 ]; then warn " ⚠ Found ${error_count} error(s) in recent logs" info " View logs: kubectl logs ${pod} -n ${NAMESPACE}" else log " ✓ No errors in recent logs" fi return 0 } check_provider_config() { log "Checking ProviderConfig..." if kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" &> /dev/null; then log " ✓ ProviderConfig exists: ${PROVIDER_CONFIG_NAME}" # Check status local status=$(kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null) if [ "$status" = "True" ]; then log " ✓ ProviderConfig status: Ready" else warn " ⚠ ProviderConfig status: ${status:-Unknown}" return 1 fi else error " ✗ ProviderConfig missing: ${PROVIDER_CONFIG_NAME}" return 1 fi return 0 } check_secret() { log "Checking credentials secret..." local secret_name=$(kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" -o jsonpath='{.spec.credentials.secretRef.name}' 2>/dev/null) local secret_namespace=$(kubectl get providerconfig "${PROVIDER_CONFIG_NAME}" -o jsonpath='{.spec.credentials.secretRef.namespace}' 2>/dev/null) if [ -z "$secret_name" ]; then warn " ⚠ No secret reference found in ProviderConfig" return 1 fi if kubectl get secret "${secret_name}" -n "${secret_namespace:-${NAMESPACE}}" &> /dev/null; then log " ✓ Secret exists: ${secret_name} (namespace: ${secret_namespace:-${NAMESPACE}})" else error " ✗ Secret missing: ${secret_name}" return 1 fi return 0 } show_provider_info() { info "" info "Provider Information:" info "====================" local pod=$(kubectl get pod -n "${NAMESPACE}" -l app="${PROVIDER_NAME}" -o jsonpath='{.items[0].metadata.name}' 2>/dev/null) if [ -n "$pod" ]; then info "Pod: ${pod}" info "Namespace: ${NAMESPACE}" info "" info "Recent logs (last 10 lines):" kubectl logs "${pod}" -n "${NAMESPACE}" --tail=10 2>&1 | sed 's/^/ /' fi } main() { echo "" echo "╔══════════════════════════════════════════════════════════════╗" echo "║ Crossplane Proxmox Provider - Deployment Check ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" if ! check_kubectl; then exit 1 fi local errors=0 check_crds || ((errors++)) echo "" check_provider_deployment || ((errors++)) echo "" check_provider_pod || ((errors++)) echo "" check_provider_config || ((errors++)) echo "" check_secret || ((errors++)) echo "" if [ $errors -eq 0 ]; then log "✓ All checks passed!" show_provider_info echo "" log "Provider is ready to use!" else error "✗ Found ${errors} issue(s)" echo "" warn "Review the errors above and fix them before proceeding" show_provider_info exit 1 fi } main "$@"