#!/usr/bin/env bash # # Phase 2 Validation: Core Services # # Validates that RFC 0040 components are deployed and healthy: # - Vault (unsealed, HA mode) # - Keycloak (realm exists, healthy) # - Forgejo (SSO working) # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' PASSED=0 FAILED=0 WARNINGS=0 log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_pass() { echo -e "${GREEN}[PASS]${NC} $1" ((PASSED++)) } log_fail() { echo -e "${RED}[FAIL]${NC} $1" ((FAILED++)) } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" ((WARNINGS++)) } check_vault() { log_info "Checking Vault status..." # Check if namespace exists if ! kubectl get namespace vault &> /dev/null; then log_fail "vault namespace does not exist" return fi # Check pod count local pod_count pod_count=$(kubectl -n vault get pods -l app=vault -o json | jq '[.items[] | select(.status.phase == "Running")] | length') if [ "$pod_count" -ge 1 ]; then log_pass "Vault has $pod_count running pods" else log_fail "Vault has no running pods" return fi # Check Vault seal status local vault_status vault_status=$(kubectl -n vault exec vault-0 -- vault status -format=json 2>/dev/null || echo '{}') local initialized initialized=$(echo "$vault_status" | jq -r '.initialized // false') local sealed sealed=$(echo "$vault_status" | jq -r '.sealed // true') if [ "$initialized" = "true" ]; then log_pass "Vault is initialized" else log_fail "Vault is not initialized" fi if [ "$sealed" = "false" ]; then log_pass "Vault is unsealed" else log_fail "Vault is sealed - must be unsealed before services can access secrets" fi # Check HA status local ha_enabled ha_enabled=$(echo "$vault_status" | jq -r '.ha_enabled // false') if [ "$ha_enabled" = "true" ]; then log_pass "Vault HA mode is enabled" else log_warn "Vault HA mode is not enabled" fi # Check Vault health endpoint local health_code health_code=$(kubectl -n vault exec vault-0 -- wget -q -O /dev/null -S http://127.0.0.1:8200/v1/sys/health 2>&1 | grep "HTTP/" | awk '{print $2}' || echo "0") if [ "$health_code" = "200" ] || [ "$health_code" = "429" ]; then log_pass "Vault health endpoint responding (HTTP $health_code)" else log_warn "Vault health endpoint returned HTTP $health_code" fi } check_keycloak() { log_info "Checking Keycloak status..." # Check if namespace exists if ! kubectl get namespace keycloak &> /dev/null; then log_fail "keycloak namespace does not exist" return fi # Check pod count and health local ready_pods ready_pods=$(kubectl -n keycloak get pods -l app=keycloak -o json | jq '[.items[] | select(.status.phase == "Running") | select(.status.containerStatuses[]?.ready == true)] | length') if [ "$ready_pods" -ge 1 ]; then log_pass "Keycloak has $ready_pods ready pods" else log_fail "Keycloak has no ready pods" return fi # Check Keycloak service local svc_exists svc_exists=$(kubectl -n keycloak get svc keycloak -o name 2>/dev/null || echo "") if [ -n "$svc_exists" ]; then log_pass "Keycloak service exists" else log_fail "Keycloak service does not exist" fi # Check for coherence realm (via API if accessible) # This requires port-forward or ingress access log_info "Note: Verify 'coherence' realm exists via Keycloak Web UI" # Check ingress/route local ingress_exists ingress_exists=$(kubectl get ingress -A -o json 2>/dev/null | jq '[.items[] | select(.spec.rules[]?.host | contains("auth"))] | length') if [ "$ingress_exists" -ge 1 ]; then log_pass "Keycloak ingress configured" else log_warn "No Keycloak ingress found - may be using LoadBalancer service" fi } check_forgejo() { log_info "Checking Forgejo status..." # Check if namespace exists if ! kubectl get namespace forgejo &> /dev/null; then log_fail "forgejo namespace does not exist" return fi # Check pod health local ready_pods ready_pods=$(kubectl -n forgejo get pods -l app=forgejo -o json | jq '[.items[] | select(.status.phase == "Running") | select(.status.containerStatuses[]?.ready == true)] | length') if [ "$ready_pods" -ge 1 ]; then log_pass "Forgejo has $ready_pods ready pods" else log_fail "Forgejo has no ready pods" return fi # Check Forgejo service local svc_exists svc_exists=$(kubectl -n forgejo get svc forgejo -o name 2>/dev/null || echo "") if [ -n "$svc_exists" ]; then log_pass "Forgejo service exists" else log_fail "Forgejo service does not exist" fi # Check PVC local pvc_bound pvc_bound=$(kubectl -n forgejo get pvc -o json | jq '[.items[] | select(.status.phase == "Bound")] | length') if [ "$pvc_bound" -ge 1 ]; then log_pass "Forgejo PVC is bound" else log_warn "No bound PVC found for Forgejo" fi # Check OAuth configuration local oauth_config oauth_config=$(kubectl -n forgejo get configmap -o json 2>/dev/null | jq '[.items[] | select(.metadata.name | contains("oauth"))] | length') if [ "$oauth_config" -ge 1 ]; then log_pass "Forgejo OAuth configuration found" else log_warn "No OAuth configuration found - SSO may not be configured" fi } check_sso_integration() { log_info "Checking SSO integration..." # This is a placeholder for SSO checks # In practice, you would test OAuth flows log_info "Note: Manually verify SSO by logging into Forgejo with Keycloak" log_info " 1. Navigate to Forgejo web UI" log_info " 2. Click 'Sign in with Keycloak'" log_info " 3. Verify redirect to Keycloak login" log_info " 4. Verify successful login and redirect back" } print_summary() { echo "" echo "========================================" echo "Phase 2 Validation Summary" echo "========================================" echo -e " ${GREEN}Passed:${NC} $PASSED" echo -e " ${RED}Failed:${NC} $FAILED" echo -e " ${YELLOW}Warnings:${NC} $WARNINGS" echo "========================================" if [ "$FAILED" -gt 0 ]; then echo "" echo -e "${RED}Phase 2 validation FAILED${NC}" echo "Please fix the issues above before proceeding to Phase 3." exit 1 elif [ "$WARNINGS" -gt 0 ]; then echo "" echo -e "${YELLOW}Phase 2 validation passed with warnings${NC}" echo "Review warnings above. You may proceed to Phase 3." exit 0 else echo "" echo -e "${GREEN}Phase 2 validation PASSED${NC}" echo "You may proceed to Phase 3." exit 0 fi } main() { echo "========================================" echo "Phase 2 Validation: Core Services" echo "========================================" echo "" check_vault check_keycloak check_forgejo check_sso_integration print_summary } main "$@"