#!/bin/bash set -e set -o pipefail # Initialize Wild Cloud environment if [ -z "${WC_ROOT}" ]; then print "WC_ROOT is not set." exit 1 else source "${WC_ROOT}/scripts/common.sh" init_wild_env fi CLUSTER_SETUP_DIR="${WC_HOME}/setup/cluster-services" CERT_MANAGER_DIR="${CLUSTER_SETUP_DIR}/cert-manager" print_header "Setting up cert-manager" # Check Traefik dependency print_info "Verifying Traefik is ready (required for cert-manager)..." kubectl wait --for=condition=Available deployment/traefik -n traefik --timeout=60s 2>/dev/null || { print_warning "Traefik not ready, but continuing with cert-manager installation" print_info "Note: cert-manager may not work properly without Traefik" } # Templates should already be compiled by wild-cluster-services-configure print_info "Using pre-compiled cert-manager templates..." if [ ! -d "${CERT_MANAGER_DIR}/kustomize" ]; then print_error "Compiled templates not found. Run 'wild-cluster-services-configure' first." exit 1 fi print_info "Setting up cert-manager..." # Install cert-manager using the official installation method # This installs CRDs, controllers, and webhook components print_info "Installing cert-manager components..." # Using stable URL for cert-manager installation kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.1/cert-manager.yaml || \ kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.13.1/cert-manager.yaml # Wait for cert-manager to be ready print_info "Waiting for cert-manager to be ready..." kubectl wait --for=condition=Available deployment/cert-manager -n cert-manager --timeout=120s kubectl wait --for=condition=Available deployment/cert-manager-cainjector -n cert-manager --timeout=120s kubectl wait --for=condition=Available deployment/cert-manager-webhook -n cert-manager --timeout=120s # Ensure webhook is fully operational print_info "Verifying cert-manager webhook is fully operational..." until kubectl get validatingwebhookconfigurations cert-manager-webhook &>/dev/null; do print_info "Waiting for cert-manager webhook to register..." sleep 5 done # Test webhook connectivity before proceeding print_info "Testing webhook connectivity..." kubectl auth can-i create certificates.cert-manager.io --as=system:serviceaccount:cert-manager:cert-manager # Setup Cloudflare API token for DNS01 challenges print_info "Creating Cloudflare API token secret..." CLOUDFLARE_API_TOKEN=$(wild-secret cloudflare.token) || exit 1 # Validate Cloudflare API token permissions print_info "Validating Cloudflare API token permissions..." validate_cloudflare_token() { local token="$1" if ! command -v curl &>/dev/null; then print_warning "curl not available, skipping token validation" return 0 fi print_info "Testing Cloudflare API token..." local response response=$(curl -s -H "Authorization: Bearer $token" \ "https://api.cloudflare.com/client/v4/zones") if echo "$response" | grep -q '"success":true'; then print_success "Cloudflare API token is valid and has zone access" return 0 else print_error "Cloudflare token validation failed" print_info "Response: $response" print_info "Please ensure your token has Zone - Zone - Read permission" return 1 fi } validate_cloudflare_token "$CLOUDFLARE_API_TOKEN" || { print_error "Cloudflare token validation failed. Please check token permissions." print_info "Required permissions: Zone - Zone - Read, Zone - DNS - Edit" exit 1 } kubectl create secret generic cloudflare-api-token \ --namespace cert-manager \ --from-literal=api-token="${CLOUDFLARE_API_TOKEN}" \ --dry-run=client -o yaml | kubectl apply -f - # Configure cert-manager to use external DNS for challenge verification print_info "Configuring cert-manager to use external DNS servers..." kubectl patch deployment cert-manager -n cert-manager --patch ' spec: template: spec: dnsPolicy: None dnsConfig: nameservers: - "1.1.1.1" - "8.8.8.8" searches: - cert-manager.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: "5"' # Wait for cert-manager to restart with new DNS config print_info "Waiting for cert-manager to restart with new DNS configuration..." kubectl rollout status deployment/cert-manager -n cert-manager --timeout=120s # Apply Let's Encrypt issuers and certificates using kustomize print_info "Creating Let's Encrypt issuers and certificates..." kubectl apply -k ${CERT_MANAGER_DIR}/kustomize # Wait for issuers to be ready print_info "Waiting for Let's Encrypt issuers to be ready..." kubectl wait --for=condition=Ready clusterissuer/letsencrypt-prod --timeout=60s || print_warning "Production issuer not ready, proceeding anyway..." kubectl wait --for=condition=Ready clusterissuer/letsencrypt-staging --timeout=60s || print_warning "Staging issuer not ready, proceeding anyway..." # Validate DNS resolution using temporary test pod print_info "Validating DNS resolution for ACME challenges..." domain=$(wild-config cluster.certManager.cloudflare.domain) print_info "Testing DNS resolution for domain: $domain" # Create temporary pod with DNS utilities kubectl run dns-test --image=busybox:1.35 --rm -i --restart=Never -n cert-manager -- \ nslookup -type=SOA "$domain" 1.1.1.1 &>/dev/null && \ print_success "DNS resolution working for ACME challenges" || \ print_warning "DNS resolution issues may affect ACME challenges" print_info "Wildcard certificate creation initiated. This may take some time to complete depending on DNS propagation." # Wait for the certificates to be issued (with a timeout) print_info "Waiting for wildcard certificates to be ready (this may take several minutes)..." kubectl wait --for=condition=Ready certificate wildcard-internal-wild-cloud -n cert-manager --timeout=300s || true kubectl wait --for=condition=Ready certificate wildcard-wild-cloud -n cert-manager --timeout=300s || true print_success "cert-manager setup complete!" echo "" print_info "To verify the installation:" print_info " kubectl get pods -n cert-manager" print_info " kubectl get clusterissuers" print_info " kubectl get certificates -n cert-manager"