#!/bin/bash # Configuration Management Validator (K8s-equivalent) # Validates configuration files and secrets before deployment set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration CONFIG_DIR="$PROJECT_ROOT/config" SECRETS_DIR="$PROJECT_ROOT/secrets" echo -e "${BLUE}🔍 Configuration Management Validator${NC}" echo -e "${BLUE}======================================${NC}" echo # Function to validate YAML syntax validate_yaml() { local file="$1" echo -n " Validating $file... " if command -v yq > /dev/null 2>&1; then if yq eval '.' "$file" > /dev/null 2>&1; then echo -e "${GREEN}✅ Valid${NC}" return 0 else echo -e "${RED}❌ Invalid YAML${NC}" return 1 fi elif command -v python3 > /dev/null 2>&1; then if python3 -c "import yaml; yaml.safe_load(open('$file'))" > /dev/null 2>&1; then echo -e "${GREEN}✅ Valid${NC}" return 0 else echo -e "${RED}❌ Invalid YAML${NC}" return 1 fi else echo -e "${YELLOW}⚠️ Cannot validate (no yq or python3)${NC}" return 0 fi } # Function to check required secrets check_secrets() { local secrets_dir="$1" local service_name="$2" echo "📁 Checking $service_name secrets:" local required_secrets case "$service_name" in "app") required_secrets=( "postgres-password.txt" "minio-access-key.txt" "minio-secret-key.txt" "platform-vehicles-api-key.txt" "platform-tenants-api-key.txt" "service-auth-token.txt" "auth0-client-secret.txt" "google-maps-api-key.txt" ) ;; "platform") required_secrets=( "platform-db-password.txt" "vehicles-db-password.txt" "vehicles-api-key.txt" "tenants-api-key.txt" "allowed-service-tokens.txt" ) ;; esac local missing_secrets=() for secret in "${required_secrets[@]}"; do local secret_file="$secrets_dir/$secret" if [[ -f "$secret_file" ]]; then # Check if file is not empty if [[ -s "$secret_file" ]]; then echo -e " $secret: ${GREEN}✅ Present${NC}" else echo -e " $secret: ${YELLOW}⚠️ Empty${NC}" missing_secrets+=("$secret") fi else echo -e " $secret: ${RED}❌ Missing${NC}" missing_secrets+=("$secret") fi done if [[ ${#missing_secrets[@]} -gt 0 ]]; then echo -e " ${RED}Missing secrets: ${missing_secrets[*]}${NC}" return 1 fi return 0 } # Function to validate configuration structure validate_config_structure() { echo "🏗️ Validating configuration structure:" local required_configs=( "$CONFIG_DIR/app/production.yml" "$CONFIG_DIR/platform/production.yml" "$CONFIG_DIR/shared/production.yml" ) local missing_configs=() for config in "${required_configs[@]}"; do if [[ -f "$config" ]]; then echo -e " $(basename "$config"): ${GREEN}✅ Present${NC}" if ! validate_yaml "$config"; then missing_configs+=("$config") fi else echo -e " $(basename "$config"): ${RED}❌ Missing${NC}" missing_configs+=("$config") fi done if [[ ${#missing_configs[@]} -gt 0 ]]; then echo -e " ${RED}Issues with configs: ${missing_configs[*]}${NC}" return 1 fi return 0 } # Function to validate docker-compose configuration validate_docker_compose() { echo "🐳 Validating Docker Compose configuration:" local compose_file="$PROJECT_ROOT/docker-compose.yml" if [[ ! -f "$compose_file" ]]; then echo -e " ${RED}❌ docker-compose.yml not found${NC}" return 1 fi echo -n " Checking docker-compose.yml syntax... " if docker compose -f "$compose_file" config > /dev/null 2>&1; then echo -e "${GREEN}✅ Valid${NC}" else echo -e "${RED}❌ Invalid${NC}" return 1 fi # Check for required volume mounts echo -n " Checking configuration mounts... " if grep -q "config.*production.yml" "$compose_file" && grep -q "/run/secrets" "$compose_file"; then echo -e "${GREEN}✅ Configuration mounts present${NC}" else echo -e "${YELLOW}⚠️ Configuration mounts may be missing${NC}" fi return 0 } # Function to generate missing secrets template generate_secrets_template() { echo "📝 Generating secrets template:" for service in app platform; do local secrets_dir="$SECRETS_DIR/$service" local template_file="$secrets_dir/.secrets-setup.sh" echo " Creating $service secrets setup script..." cat > "$template_file" << 'EOF' #!/bin/bash # Auto-generated secrets setup script # Run this script to create placeholder secret files SECRETS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" echo "Setting up secrets in $SECRETS_DIR" EOF # Add service-specific secret creation commands case "$service" in "app") cat >> "$template_file" << 'EOF' # Application secrets echo "localdev123" > "$SECRETS_DIR/postgres-password.txt" echo "minioadmin" > "$SECRETS_DIR/minio-access-key.txt" echo "minioadmin123" > "$SECRETS_DIR/minio-secret-key.txt" echo "mvp-platform-vehicles-secret-key" > "$SECRETS_DIR/platform-vehicles-api-key.txt" echo "mvp-platform-tenants-secret-key" > "$SECRETS_DIR/platform-tenants-api-key.txt" echo "admin-backend-service-token" > "$SECRETS_DIR/service-auth-token.txt" echo "your-auth0-client-secret" > "$SECRETS_DIR/auth0-client-secret.txt" echo "your-google-maps-api-key" > "$SECRETS_DIR/google-maps-api-key.txt" EOF ;; "platform") cat >> "$template_file" << 'EOF' # Platform secrets echo "platform123" > "$SECRETS_DIR/platform-db-password.txt" echo "platform123" > "$SECRETS_DIR/vehicles-db-password.txt" echo "mvp-platform-vehicles-secret-key" > "$SECRETS_DIR/vehicles-api-key.txt" echo "mvp-platform-tenants-secret-key" > "$SECRETS_DIR/tenants-api-key.txt" echo "admin-backend-service-token,mvp-platform-vehicles-service-token" > "$SECRETS_DIR/allowed-service-tokens.txt" EOF ;; esac cat >> "$template_file" << 'EOF' echo "✅ Secrets setup complete for this service" echo "⚠️ Remember to update with real values for production!" EOF chmod +x "$template_file" done } # Main validation main() { local validation_failed=false echo "🚀 Starting configuration validation..." echo # Validate configuration structure if ! validate_config_structure; then validation_failed=true fi echo # Check secrets echo "🔐 Validating secrets:" if ! check_secrets "$SECRETS_DIR/app" "app"; then validation_failed=true fi echo if ! check_secrets "$SECRETS_DIR/platform" "platform"; then validation_failed=true fi echo # Validate Docker Compose if ! validate_docker_compose; then validation_failed=true fi echo if [[ "$validation_failed" == "true" ]]; then echo -e "${RED}❌ Validation failed!${NC}" echo echo "To fix issues:" echo " 1. Run: ./scripts/config-validator.sh --generate-templates" echo " 2. Update secret values in secrets/ directories" echo " 3. Re-run validation" if [[ "$1" == "--generate-templates" ]]; then echo generate_secrets_template fi exit 1 else echo -e "${GREEN}✅ All validations passed!${NC}" echo -e "${GREEN}🎉 Configuration is ready for K8s-equivalent deployment${NC}" exit 0 fi } # Handle command line arguments if [[ "$1" == "--generate-templates" ]]; then generate_secrets_template echo -e "${GREEN}✅ Secret templates generated${NC}" echo "Run the generated scripts in secrets/app/ and secrets/platform/" exit 0 elif [[ "$1" == "--help" ]]; then echo "Configuration Management Validator" echo echo "Usage:" echo " $0 - Run full validation" echo " $0 --generate-templates - Generate secret setup scripts" echo " $0 --help - Show this help" exit 0 fi main "$@"