Files
rxminder/scripts/k8s-deploy-template.sh

331 lines
9.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# 🚀 RxMinder Template-based Kubernetes Deployment Script
# This script processes template files and applies them to Kubernetes
set -euo pipefail
# Script configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
K8S_DIR="$(dirname "$SCRIPT_DIR")/k8s"
ENV_FILE="$(dirname "$SCRIPT_DIR")/.env"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
print_status() {
echo -e "${BLUE}$1${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
# Function to load environment variables
load_env() {
if [[ -f "$ENV_FILE" ]]; then
print_status "Loading environment variables from .env..."
# Export variables from .env file
set -a
source "$ENV_FILE"
set +a
print_success "Environment variables loaded"
else
print_warning ".env file not found at $ENV_FILE"
print_warning "Using default values. Copy .env.example to .env and customize."
fi
}
# Function to substitute environment variables in templates
substitute_template() {
local template_file="$1"
local output_file="$2"
print_status "Processing template: $template_file"
# Use envsubst to substitute environment variables
if command -v envsubst >/dev/null 2>&1; then
envsubst < "$template_file" > "$output_file"
else
print_error "envsubst not found. Please install gettext package."
exit 1
fi
print_success "Generated: $output_file"
}
# Function to apply Kubernetes resources
apply_k8s_resource() {
local resource_file="$1"
if [[ -f "$resource_file" ]]; then
print_status "Applying Kubernetes resource: $resource_file"
if kubectl apply -f "$resource_file"; then
print_success "Applied: $resource_file"
else
print_error "Failed to apply: $resource_file"
return 1
fi
else
print_warning "Resource file not found: $resource_file"
fi
}
# Function to validate required environment variables
validate_env() {
local required_vars=(
"APP_NAME"
"DOCKER_IMAGE"
"COUCHDB_USER"
"COUCHDB_PASSWORD"
"INGRESS_HOST"
"STORAGE_CLASS"
"STORAGE_SIZE"
)
local missing_vars=()
for var in "${required_vars[@]}"; do
if [[ -z "${!var:-}" ]]; then
missing_vars+=("$var")
fi
done
if [[ ${#missing_vars[@]} -gt 0 ]]; then
print_error "Missing required environment variables:"
for var in "${missing_vars[@]}"; do
echo -e " ${RED}- $var${NC}"
done
print_warning "Please update your .env file with these variables."
exit 1
fi
print_success "All required environment variables are set"
}
# Function to process all templates
process_templates() {
local temp_dir="/tmp/rxminder-k8s-$$"
mkdir -p "$temp_dir"
print_status "Processing Kubernetes templates..."
# Find all template files
local template_files=(
"$K8S_DIR/couchdb-secret.yaml.template"
"$K8S_DIR/ingress.yaml.template"
)
# Add any additional template files
for template_file in "$K8S_DIR"/*.template; do
if [[ -f "$template_file" ]]; then
template_files+=("$template_file")
fi
done
# Process each template
for template_file in "${template_files[@]}"; do
if [[ -f "$template_file" ]]; then
local base_name
base_name="$(basename "$template_file" .template)"
local output_file="$temp_dir/$base_name"
substitute_template "$template_file" "$output_file"
fi
done
echo "$temp_dir"
}
# Function to deploy resources in correct order
deploy_resources() {
local resource_dir="$1"
print_status "Deploying Kubernetes resources..."
# Deploy in specific order for dependencies
local deployment_order=(
"couchdb-secret.yaml"
"couchdb-pvc.yaml"
"couchdb-service.yaml"
"couchdb-statefulset.yaml"
"configmap.yaml"
"frontend-deployment.yaml"
"frontend-service.yaml"
"ingress.yaml"
"$K8S_DIR/network-policy.yaml"
"$K8S_DIR/hpa.yaml"
)
for resource in "${deployment_order[@]}"; do
if [[ "$resource" == *.yaml ]]; then
# Check if it's a template-generated file
if [[ -f "$resource_dir/$(basename "$resource")" ]]; then
apply_k8s_resource "$resource_dir/$(basename "$resource")"
else
# Apply directly from k8s directory
apply_k8s_resource "$resource"
fi
fi
done
}
# Function to run database seeding job
run_db_seed() {
print_status "Running database seed job..."
# Apply the db-seed-job (which uses environment variables from secret)
if kubectl apply -f "$K8S_DIR/db-seed-job.yaml"; then
print_success "Database seed job submitted"
# Wait for job completion
print_status "Waiting for database seed job to complete..."
if kubectl wait --for=condition=complete --timeout=300s job/db-seed-job; then
print_success "Database seeding completed successfully"
else
print_warning "Database seed job may have failed. Check logs:"
echo "kubectl logs job/db-seed-job"
fi
else
print_error "Failed to apply database seed job"
return 1
fi
}
# Function to display deployment status
show_status() {
print_status "Deployment Status:"
echo
print_status "Pods:"
kubectl get pods -l app="${APP_NAME:-rxminder}"
echo
print_status "Services:"
kubectl get services -l app="${APP_NAME:-rxminder}"
echo
print_status "Ingress:"
kubectl get ingress
echo
if [[ -n "${INGRESS_HOST:-}" ]]; then
print_success "Application should be available at: http://${INGRESS_HOST}"
fi
}
# Function to cleanup temporary files
cleanup() {
if [[ -n "${temp_dir:-}" && -d "$temp_dir" ]]; then
rm -rf "$temp_dir"
fi
}
# Main deployment function
main() {
local command="${1:-deploy}"
case "$command" in
"deploy"|"apply")
print_status "🚀 Starting RxMinder Kubernetes deployment..."
echo
# Set default values for required variables
export APP_NAME="${APP_NAME:-rxminder}"
export DOCKER_IMAGE="${DOCKER_IMAGE:-gitea-http.taildb3494.ts.net/will/meds:latest}"
export COUCHDB_USER="${COUCHDB_USER:-admin}"
export COUCHDB_PASSWORD="${COUCHDB_PASSWORD:-change-this-secure-password}"
export INGRESS_HOST="${INGRESS_HOST:-rxminder.local}"
export STORAGE_CLASS="${STORAGE_CLASS:-longhorn}"
export STORAGE_SIZE="${STORAGE_SIZE:-5Gi}"
load_env
validate_env
# Process templates
temp_dir=$(process_templates)
trap cleanup EXIT
# Deploy resources
deploy_resources "$temp_dir"
# Run database seeding
run_db_seed
# Show status
echo
show_status
print_success "🎉 RxMinder deployment completed!"
;;
"status")
load_env
show_status
;;
"delete"|"cleanup")
print_status "🗑️ Cleaning up RxMinder deployment..."
kubectl delete all,pvc,secret,configmap,ingress -l app="${APP_NAME:-rxminder}" || true
kubectl delete job db-seed-job || true
print_success "Cleanup completed"
;;
"help"|"-h"|"--help")
echo "RxMinder Kubernetes Deployment Script"
echo
echo "Usage: $0 [command]"
echo
echo "Commands:"
echo " deploy Deploy RxMinder to Kubernetes (default)"
echo " status Show deployment status"
echo " delete Delete all RxMinder resources"
echo " help Show this help message"
echo
echo "Environment variables (set in .env):"
echo " APP_NAME Application name (default: rxminder)"
echo " DOCKER_IMAGE Container image to deploy"
echo " COUCHDB_USER Database username (default: admin)"
echo " COUCHDB_PASSWORD Database password (required)"
echo " INGRESS_HOST Ingress hostname (required)"
echo " STORAGE_CLASS Storage class for PVCs (default: longhorn)"
echo " STORAGE_SIZE Storage size for database (default: 5Gi)"
;;
*)
print_error "Unknown command: $command"
echo "Use '$0 help' for usage information"
exit 1
;;
esac
}
# Check if kubectl is available
if ! command -v kubectl >/dev/null 2>&1; then
print_error "kubectl not found. Please install kubectl and configure it to connect to your cluster."
exit 1
fi
# Check if envsubst is available
if ! command -v envsubst >/dev/null 2>&1; then
print_error "envsubst not found. Please install the gettext package:"
echo " Ubuntu/Debian: sudo apt-get install gettext"
echo " macOS: brew install gettext"
echo " RHEL/CentOS: sudo yum install gettext"
exit 1
fi
# Run main function
main "$@"