#!/bin/bash # generate-config.sh # Generates config.env files for Kustomize from environment variables # Usage: ./scripts/generate-config.sh [environment] # Example: ./scripts/generate-config.sh dev set -euo pipefail # Default environment ENVIRONMENT=${1:-dev} SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Color codes for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Load environment variables from various sources load_env_files() { local env_files=( "$HOME/.env" "$PROJECT_ROOT/.env" "$PROJECT_ROOT/.env.$ENVIRONMENT" "$PROJECT_ROOT/.env.local" ) print_status "Loading environment variables..." for env_file in "${env_files[@]}"; do if [[ -f "$env_file" ]]; then print_status "Loading: $env_file" # Source the file in a subshell to avoid polluting current environment set -a source "$env_file" set +a else print_warning "File not found: $env_file" fi done } # Generate config.env for base configuration generate_base_config() { local config_file="$PROJECT_ROOT/k8s-kustomize/base/config.env" local temp_file=$(mktemp) print_status "Generating base config.env..." cat > "$temp_file" << EOF # Base configuration for rxminder application # Generated automatically from environment variables # Generated on: $(date) # Environment: $ENVIRONMENT # Application Environment NODE_ENV=${NODE_ENV:-production} LOG_LEVEL=${LOG_LEVEL:-info} # API Configuration REACT_APP_API_URL=${REACT_APP_API_URL:-http://rxminder-couchdb-service:5984} # Feature Flags ENABLE_MONITORING=${ENABLE_MONITORING:-false} DEBUG=${DEBUG:-false} # Cache Configuration CACHE_TTL=${CACHE_TTL:-1800} # Database Configuration DB_HOST=${DB_HOST:-rxminder-couchdb-service} DB_PORT=${DB_PORT:-5984} COUCHDB_DATABASE_NAME=${COUCHDB_DATABASE_NAME:-meds_app} # Security Configuration ENABLE_CORS=${ENABLE_CORS:-true} CORS_ORIGIN=${CORS_ORIGIN:-*} # Performance Configuration REQUEST_TIMEOUT=${REQUEST_TIMEOUT:-30000} MAX_CONNECTIONS=${MAX_CONNECTIONS:-100} # Logging Configuration LOG_FORMAT=${LOG_FORMAT:-json} LOG_TIMESTAMP=${LOG_TIMESTAMP:-true} # Health Check Configuration HEALTH_CHECK_INTERVAL=${HEALTH_CHECK_INTERVAL:-30} READINESS_CHECK_TIMEOUT=${READINESS_CHECK_TIMEOUT:-5} # Application Metadata APP_NAME=${APP_NAME:-rxminder} APP_VERSION=${APP_VERSION:-1.0.0} # Container Registry REGISTRY_URL=${REGISTRY_URL:-gitea-http.taildb3494.ts.net} IMAGE_REPOSITORY=${IMAGE_REPOSITORY:-will/rxminder} # Ingress Configuration INGRESS_CLASS=${INGRESS_CLASS:-nginx} CERT_MANAGER_ISSUER=${CERT_MANAGER_ISSUER:-letsencrypt-prod} # Monitoring and Observability ENABLE_METRICS=${ENABLE_METRICS:-false} METRICS_PORT=${METRICS_PORT:-9090} ENABLE_TRACING=${ENABLE_TRACING:-false} # Development specific (will be overridden in overlays) DEV_MODE=${DEV_MODE:-false} HOT_RELOAD=${HOT_RELOAD:-false} EOF # Move temp file to final location mv "$temp_file" "$config_file" print_success "Generated: $config_file" } # Generate environment-specific config generate_environment_config() { local overlay_dir="$PROJECT_ROOT/k8s-kustomize/overlays/$ENVIRONMENT" local env_config_file="$overlay_dir/config.env" if [[ ! -d "$overlay_dir" ]]; then print_error "Environment overlay directory not found: $overlay_dir" return 1 fi print_status "Generating environment-specific config for: $ENVIRONMENT" case "$ENVIRONMENT" in "dev"|"development") generate_dev_config "$env_config_file" ;; "prod"|"production") generate_prod_config "$env_config_file" ;; "staging") generate_staging_config "$env_config_file" ;; *) print_warning "Unknown environment: $ENVIRONMENT. Generating generic config." generate_generic_config "$env_config_file" ;; esac } # Generate development-specific configuration generate_dev_config() { local config_file="$1" local temp_file=$(mktemp) cat > "$temp_file" << EOF # Development environment configuration # Generated on: $(date) NODE_ENV=development LOG_LEVEL=debug DEBUG=true ENABLE_MONITORING=false DEV_MODE=true HOT_RELOAD=true # Development URLs (override if needed) REACT_APP_API_URL=${DEV_API_URL:-http://rxminder-couchdb-service:5984} CORS_ORIGIN=${DEV_CORS_ORIGIN:-*} # Development domain INGRESS_HOST=${DEV_INGRESS_HOST:-rxminder-dev.local} # Relaxed timeouts for debugging REQUEST_TIMEOUT=60000 HEALTH_CHECK_INTERVAL=60 # Development image tag IMAGE_TAG=${DEV_IMAGE_TAG:-dev} EOF mv "$temp_file" "$config_file" print_success "Generated development config: $config_file" } # Generate production-specific configuration generate_prod_config() { local config_file="$1" local temp_file=$(mktemp) cat > "$temp_file" << EOF # Production environment configuration # Generated on: $(date) NODE_ENV=production LOG_LEVEL=${PROD_LOG_LEVEL:-warn} DEBUG=false ENABLE_MONITORING=true DEV_MODE=false # Production URLs REACT_APP_API_URL=${PROD_API_URL:-http://rxminder-couchdb-service:5984} CORS_ORIGIN=${PROD_CORS_ORIGIN:-https://rxminder.yourdomain.com} # Production domain INGRESS_HOST=${PROD_INGRESS_HOST:-rxminder.yourdomain.com} # Production performance settings CACHE_TTL=3600 REQUEST_TIMEOUT=30000 MAX_CONNECTIONS=200 # Production monitoring ENABLE_METRICS=true ENABLE_TRACING=true # Production image tag IMAGE_TAG=${PROD_IMAGE_TAG:-v1.0.0} # Security settings ENABLE_SECURITY_HEADERS=true ENABLE_RATE_LIMITING=true EOF mv "$temp_file" "$config_file" print_success "Generated production config: $config_file" } # Generate staging-specific configuration generate_staging_config() { local config_file="$1" local temp_file=$(mktemp) cat > "$temp_file" << EOF # Staging environment configuration # Generated on: $(date) NODE_ENV=staging LOG_LEVEL=${STAGING_LOG_LEVEL:-info} DEBUG=false ENABLE_MONITORING=true DEV_MODE=false # Staging URLs REACT_APP_API_URL=${STAGING_API_URL:-http://rxminder-couchdb-service:5984} CORS_ORIGIN=${STAGING_CORS_ORIGIN:-https://staging.rxminder.yourdomain.com} # Staging domain INGRESS_HOST=${STAGING_INGRESS_HOST:-staging.rxminder.yourdomain.com} # Staging image tag IMAGE_TAG=${STAGING_IMAGE_TAG:-staging} # Enable monitoring but with relaxed settings ENABLE_METRICS=true ENABLE_TRACING=false EOF mv "$temp_file" "$config_file" print_success "Generated staging config: $config_file" } # Generate generic environment configuration generate_generic_config() { local config_file="$1" local temp_file=$(mktemp) cat > "$temp_file" << EOF # Generic environment configuration for: $ENVIRONMENT # Generated on: $(date) NODE_ENV=${ENVIRONMENT} LOG_LEVEL=${LOG_LEVEL:-info} DEBUG=${DEBUG:-false} # Image tag for this environment IMAGE_TAG=${ENVIRONMENT} EOF mv "$temp_file" "$config_file" print_success "Generated generic config: $config_file" } # Generate secrets template (not actual secrets) generate_secrets_template() { local secrets_file="$PROJECT_ROOT/k8s-kustomize/overlays/$ENVIRONMENT/secrets.env.template" local temp_file=$(mktemp) print_status "Generating secrets template..." cat > "$temp_file" << EOF # Secrets template for $ENVIRONMENT environment # Copy this to secrets.env and fill in actual values # DO NOT commit secrets.env to version control # Database credentials COUCHDB_USERNAME=${COUCHDB_USERNAME:-admin} COUCHDB_PASSWORD=CHANGE_ME_IN_${ENVIRONMENT^^} # Registry credentials (if using private registry) REGISTRY_USERNAME=${REGISTRY_USERNAME:-} REGISTRY_PASSWORD=CHANGE_ME REGISTRY_EMAIL=${REGISTRY_EMAIL:-} # TLS/SSL certificates (base64 encoded) TLS_CERT=CHANGE_ME TLS_KEY=CHANGE_ME # API keys and tokens API_SECRET_KEY=CHANGE_ME JWT_SECRET=CHANGE_ME # External service credentials MONITORING_API_KEY=CHANGE_ME SMTP_PASSWORD=CHANGE_ME EOF mv "$temp_file" "$secrets_file" print_success "Generated secrets template: $secrets_file" print_warning "Remember to create actual secrets.env file and add it to .gitignore!" } # Validate generated configuration validate_config() { local config_file="$PROJECT_ROOT/k8s-kustomize/base/config.env" print_status "Validating generated configuration..." if [[ ! -f "$config_file" ]]; then print_error "Config file not found: $config_file" return 1 fi # Check for required variables local required_vars=("APP_NAME" "NODE_ENV" "REACT_APP_API_URL") local missing_vars=() for var in "${required_vars[@]}"; do if ! grep -q "^${var}=" "$config_file"; then missing_vars+=("$var") fi done if [[ ${#missing_vars[@]} -gt 0 ]]; then print_error "Missing required variables: ${missing_vars[*]}" return 1 fi print_success "Configuration validation passed!" } # Display usage information show_usage() { cat << EOF Usage: $0 [environment] [options] ENVIRONMENTS: dev, development Generate development configuration prod, production Generate production configuration staging Generate staging configuration Generate configuration for custom environment OPTIONS: -h, --help Show this help message -v, --validate Only validate existing configuration --secrets Generate secrets template --dry-run Show what would be generated without writing files EXAMPLES: $0 dev Generate development configuration $0 prod --secrets Generate production config and secrets template $0 --validate Validate existing configuration ENVIRONMENT VARIABLES: The script will load variables from: - ~/.env (global user environment) - ./.env (project environment) - ./.env.\$ENVIRONMENT (environment-specific) - ./.env.local (local overrides) EOF } # Main execution main() { local validate_only=false local generate_secrets=false local dry_run=false # Parse command line arguments while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_usage exit 0 ;; -v|--validate) validate_only=true shift ;; --secrets) generate_secrets=true shift ;; --dry-run) dry_run=true shift ;; -*) print_error "Unknown option: $1" show_usage exit 1 ;; *) ENVIRONMENT="$1" shift ;; esac done print_status "Kustomize Config Generator" print_status "Environment: $ENVIRONMENT" if [[ "$validate_only" == "true" ]]; then validate_config exit $? fi if [[ "$dry_run" == "true" ]]; then print_status "DRY RUN MODE - No files will be written" # Set dry run flag for other functions to check export DRY_RUN=true fi # Load environment variables load_env_files # Generate configurations generate_base_config generate_environment_config if [[ "$generate_secrets" == "true" ]]; then generate_secrets_template fi # Validate generated configuration validate_config print_success "Configuration generation completed!" print_status "Next steps:" echo " 1. Review generated files in k8s-kustomize/" echo " 2. Update any environment-specific values" echo " 3. Create secrets.env files for sensitive data" echo " 4. Test with: make kustomize-dry-run-$ENVIRONMENT" } # Run main function with all arguments main "$@"