diff --git a/apps/example-admin/service.yaml b/apps/example-admin/service.yaml new file mode 100644 index 0000000..86f9313 --- /dev/null +++ b/apps/example-admin/service.yaml @@ -0,0 +1,83 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-admin + namespace: example-admin + labels: + app: example-admin +spec: + replicas: 1 + selector: + matchLabels: + app: example-admin + template: + metadata: + labels: + app: example-admin + spec: + containers: + - name: example-admin + image: nginx:latest + imagePullPolicy: Always + ports: + - containerPort: 80 + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 128Mi + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 + env: + - name: ENV_VARIABLE + value: "ENV_VALUE" +--- +apiVersion: v1 +kind: Service +metadata: + name: example-admin + namespace: example-admin + labels: + app: example-admin +spec: + selector: + app: example-admin + ports: + - port: 80 + targetPort: 80 + name: http +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: example-admin + namespace: example-admin +spec: + rules: + - host: example-admin.internal.${DOMAIN} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: example-admin + port: + number: 80 + tls: + - hosts: + - example-admin.internal.${DOMAIN} + secretName: wildcard-internal-wild-cloud-tls diff --git a/apps/example-app/service.yaml b/apps/example-app/service.yaml new file mode 100644 index 0000000..cc6be05 --- /dev/null +++ b/apps/example-app/service.yaml @@ -0,0 +1,93 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-app + namespace: default + labels: + app: example-app +spec: + replicas: 1 + selector: + matchLabels: + app: example-app + template: + metadata: + labels: + app: example-app + spec: + containers: + - name: example-app + image: nginx:alpine + imagePullPolicy: Always + ports: + - containerPort: 80 + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 128Mi + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 + env: + - name: ENV_VARIABLE + value: "ENV_VALUE" +--- +apiVersion: v1 +kind: Service +metadata: + name: example-app + namespace: default + labels: + app: example-app +spec: + selector: + app: example-app + ports: + - port: 80 + targetPort: 80 + name: http +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: example-app + namespace: default + annotations: + external-dns.alpha.kubernetes.io/target: "${DOMAIN}" + external-dns.alpha.kubernetes.io/cloudflare-proxied: "false" + + # Optional: Enable HTTPS redirection + traefik.ingress.kubernetes.io/redirect-entry-point: https + + # Optional: Enable basic auth + # traefik.ingress.kubernetes.io/auth-type: basic + # traefik.ingress.kubernetes.io/auth-secret: basic-auth +spec: + rules: + - host: example-app.${DOMAIN} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: example-app + port: + number: 80 + tls: + - hosts: + - example-app.${DOMAIN} + secretName: wildcard-wild-cloud-tls diff --git a/apps/ghost/manifests/deployment.yaml b/apps/ghost/deployment.yaml similarity index 90% rename from apps/ghost/manifests/deployment.yaml rename to apps/ghost/deployment.yaml index 2312fa0..1fba0a0 100644 --- a/apps/ghost/manifests/deployment.yaml +++ b/apps/ghost/deployment.yaml @@ -4,19 +4,19 @@ metadata: name: ghost namespace: ghost uid: d01c62ff-68a6-456a-a630-77c730bffc9b - resourceVersion: '2772014' + resourceVersion: "2772014" generation: 1 - creationTimestamp: '2025-04-27T02:01:30Z' + creationTimestamp: "2025-04-27T02:01:30Z" labels: app.kubernetes.io/component: ghost app.kubernetes.io/instance: ghost - app.kubernetes.io/managed-by: Sovereign + app.kubernetes.io/managed-by: Wild app.kubernetes.io/name: ghost app.kubernetes.io/version: 5.118.1 annotations: - deployment.kubernetes.io/revision: '1' + deployment.kubernetes.io/revision: "1" meta.helm.sh/release-name: ghost - meta.helm.sh/release-namespace: ghost + meta.helm.sh/release-namespace: ghost spec: replicas: 1 selector: @@ -29,7 +29,7 @@ spec: labels: app.kubernetes.io/component: ghost app.kubernetes.io/instance: ghost - app.kubernetes.io/managed-by: Sovereign + app.kubernetes.io/managed-by: Wild app.kubernetes.io/name: ghost app.kubernetes.io/version: 5.118.1 annotations: @@ -55,7 +55,7 @@ spec: command: - /bin/bash args: - - '-ec' + - "-ec" - > #!/bin/bash @@ -109,13 +109,13 @@ spec: protocol: TCP env: - name: BITNAMI_DEBUG - value: 'false' + value: "false" - name: ALLOW_EMPTY_PASSWORD - value: 'yes' + value: "yes" - name: GHOST_DATABASE_HOST value: ghost-mysql - name: GHOST_DATABASE_PORT_NUMBER - value: '3306' + value: "3306" - name: GHOST_DATABASE_NAME value: ghost - name: GHOST_DATABASE_USER @@ -125,7 +125,7 @@ spec: - name: GHOST_HOST value: blog.cloud.payne.io/ - name: GHOST_PORT_NUMBER - value: '2368' + value: "2368" - name: GHOST_USERNAME value: admin - name: GHOST_PASSWORD_FILE @@ -135,13 +135,13 @@ spec: - name: GHOST_BLOG_TITLE value: User's Blog - name: GHOST_ENABLE_HTTPS - value: 'yes' + value: "yes" - name: GHOST_EXTERNAL_HTTP_PORT_NUMBER - value: '80' + value: "80" - name: GHOST_EXTERNAL_HTTPS_PORT_NUMBER - value: '443' + value: "443" - name: GHOST_SKIP_BOOTSTRAP - value: 'no' + value: "no" resources: limits: cpu: 375m @@ -236,14 +236,14 @@ status: unavailableReplicas: 1 conditions: - type: Available - status: 'False' - lastUpdateTime: '2025-04-27T02:01:30Z' - lastTransitionTime: '2025-04-27T02:01:30Z' + status: "False" + lastUpdateTime: "2025-04-27T02:01:30Z" + lastTransitionTime: "2025-04-27T02:01:30Z" reason: MinimumReplicasUnavailable message: Deployment does not have minimum availability. - type: Progressing - status: 'False' - lastUpdateTime: '2025-04-27T02:11:32Z' - lastTransitionTime: '2025-04-27T02:11:32Z' + status: "False" + lastUpdateTime: "2025-04-27T02:11:32Z" + lastTransitionTime: "2025-04-27T02:11:32Z" reason: ProgressDeadlineExceeded message: ReplicaSet "ghost-586bbc6ddd" has timed out progressing. diff --git a/apps/ghost/manifests/ingress.yaml b/apps/ghost/ingress.yaml similarity index 100% rename from apps/ghost/manifests/ingress.yaml rename to apps/ghost/ingress.yaml diff --git a/apps/ghost/manifests/kustomization.yaml b/apps/ghost/kustomization.yaml similarity index 100% rename from apps/ghost/manifests/kustomization.yaml rename to apps/ghost/kustomization.yaml diff --git a/apps/ghost/manifests/networkpolicy.yaml b/apps/ghost/networkpolicy.yaml similarity index 92% rename from apps/ghost/manifests/networkpolicy.yaml rename to apps/ghost/networkpolicy.yaml index 4239c7b..c418d77 100644 --- a/apps/ghost/manifests/networkpolicy.yaml +++ b/apps/ghost/networkpolicy.yaml @@ -7,7 +7,7 @@ metadata: namespace: "default" labels: app.kubernetes.io/instance: ghost - app.kubernetes.io/managed-by: Sovereign + app.kubernetes.io/managed-by: Wild app.kubernetes.io/name: ghost app.kubernetes.io/version: 5.118.1 spec: diff --git a/apps/ghost/manifests/pdb.yaml b/apps/ghost/pdb.yaml similarity index 91% rename from apps/ghost/manifests/pdb.yaml rename to apps/ghost/pdb.yaml index 034d41e..8820e91 100644 --- a/apps/ghost/manifests/pdb.yaml +++ b/apps/ghost/pdb.yaml @@ -7,7 +7,7 @@ metadata: namespace: "default" labels: app.kubernetes.io/instance: ghost - app.kubernetes.io/managed-by: Sovereign + app.kubernetes.io/managed-by: Wild app.kubernetes.io/name: ghost app.kubernetes.io/version: 5.118.1 app.kubernetes.io/component: ghost diff --git a/apps/ghost/manifests/secrets.yaml b/apps/ghost/secrets.yaml similarity index 87% rename from apps/ghost/manifests/secrets.yaml rename to apps/ghost/secrets.yaml index 9e83163..ba8d132 100644 --- a/apps/ghost/manifests/secrets.yaml +++ b/apps/ghost/secrets.yaml @@ -7,7 +7,7 @@ metadata: namespace: "default" labels: app.kubernetes.io/instance: ghost - app.kubernetes.io/managed-by: Sovereign + app.kubernetes.io/managed-by: Wild app.kubernetes.io/name: ghost app.kubernetes.io/version: 5.118.1 type: Opaque diff --git a/apps/ghost/manifests/service-account.yaml b/apps/ghost/service-account.yaml similarity index 88% rename from apps/ghost/manifests/service-account.yaml rename to apps/ghost/service-account.yaml index 730382c..54ad1bd 100644 --- a/apps/ghost/manifests/service-account.yaml +++ b/apps/ghost/service-account.yaml @@ -7,7 +7,7 @@ metadata: namespace: "default" labels: app.kubernetes.io/instance: ghost - app.kubernetes.io/managed-by: Sovereign + app.kubernetes.io/managed-by: Wild app.kubernetes.io/name: ghost app.kubernetes.io/version: 5.118.1 app.kubernetes.io/component: ghost diff --git a/apps/ghost/manifests/svc.yaml b/apps/ghost/svc.yaml similarity index 92% rename from apps/ghost/manifests/svc.yaml rename to apps/ghost/svc.yaml index 7d4b18d..4504ebc 100644 --- a/apps/ghost/manifests/svc.yaml +++ b/apps/ghost/svc.yaml @@ -7,7 +7,7 @@ metadata: namespace: "default" labels: app.kubernetes.io/instance: ghost - app.kubernetes.io/managed-by: Sovereign + app.kubernetes.io/managed-by: Wild app.kubernetes.io/name: ghost app.kubernetes.io/version: 5.118.1 app.kubernetes.io/component: ghost diff --git a/bin/deploy-service b/bin/deploy-service deleted file mode 100755 index ab11f89..0000000 --- a/bin/deploy-service +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/bash -set -e - -# Default values -SERVICE_NAME="" -DRY_RUN=false - -# Source environment variables from load-env.sh -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_DIR="$(dirname "$SCRIPT_DIR")" -if [ -f "$REPO_DIR/load-env.sh" ]; then - source "$REPO_DIR/load-env.sh" -fi - -function show_help { - echo "Usage: $0 SERVICE_NAME [options]" - echo "" - echo "Arguments:" - echo " SERVICE_NAME Name of the service to deploy (directory name in services/)" - echo "" - echo "Optional arguments:" - echo " --dry-run Preview the processed configuration without applying" - echo " --help Show this help message" - echo "" - echo "Examples:" - echo " $0 example-app" - echo " $0 blog --dry-run" - exit 1 -} - -# Legacy mode check for type-based commands -if [[ "$1" == "--type" ]]; then - echo "Warning: Using legacy mode (generate and deploy in one step)" - echo "Consider using generate-service followed by deploy-service instead." - echo "Continuing with legacy mode..." - echo "" - - # Capture all arguments - ALL_ARGS="$@" - - # Extract service name from arguments - while [[ $# -gt 0 ]]; do - key="$1" - case $key in - --name) - SERVICE_NAME_LEGACY="$2" - break - ;; - *) - shift - ;; - esac - done - - # Generate the service configuration first - TMP_DIR=$(mktemp -d) - TMP_FILE="$TMP_DIR/service.yaml" - - $SCRIPT_DIR/generate-service $ALL_ARGS --output "$TMP_DIR" - - # Now deploy it using the service name - if [[ -n "$SERVICE_NAME_LEGACY" ]]; then - exec $0 "$SERVICE_NAME_LEGACY" - else - echo "Error: Legacy mode requires --name parameter" - exit 1 - fi - exit $? -fi - -# Parse command-line arguments -while [[ $# -gt 0 ]]; do - key="$1" - case $key in - --dry-run) - DRY_RUN=true - shift - ;; - --help) - show_help - ;; - -*) - echo "Unknown option: $1" - show_help - ;; - *) - # First non-option argument is the service name - SERVICE_NAME="$1" - shift - ;; - esac -done - -# Validate service name -if [[ -z "$SERVICE_NAME" ]]; then - echo "Error: SERVICE_NAME must be provided" - show_help -fi - -# Construct the service file path -SERVICE_FILE="$REPO_DIR/services/$SERVICE_NAME/service.yaml" -if [[ ! -f "$SERVICE_FILE" ]]; then - echo "Error: Service file not found for $SERVICE_NAME at $SERVICE_FILE" - exit 1 -fi - -# Create temporary file for the processed manifest -TEMP_FILE=$(mktemp) - -# Ensure DOMAIN is exported for template substitution -export DOMAIN="$DOMAIN" - -# Process the service file with variable substitution -echo "Processing service file: $SERVICE_FILE" -cat "$SERVICE_FILE" | envsubst > "$TEMP_FILE" - -# Handle dry run mode -if [[ "$DRY_RUN" == "true" ]]; then - cat "$TEMP_FILE" - rm "$TEMP_FILE" - exit 0 -fi - -# Extract namespace from the processed file (for creating it if needed) -NAMESPACE=$(grep -o "namespace: [a-zA-Z0-9_-]\+" "$TEMP_FILE" | head -1 | cut -d' ' -f2) -if [[ -n "$NAMESPACE" ]]; then - # Create the namespace if it doesn't exist (using kubectl create which is idempotent with --dry-run=client) - echo "Creating namespace $NAMESPACE if it doesn't exist..." - kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f - - # Copy certificates to the namespace - copy-secret cert-manager:wildcard-internal-wild-cloud-tls $NAMESPACE - copy-secret cert-manager:wildcard-wild-cloud-tls $NAMESPACE -fi - -# Apply the service -echo "Applying service configuration..." -kubectl apply -f "$TEMP_FILE" -rm "$TEMP_FILE" - -echo "✅ Service deployed successfully!" \ No newline at end of file diff --git a/bin/generate-service b/bin/generate-service deleted file mode 100755 index aa0fdb9..0000000 --- a/bin/generate-service +++ /dev/null @@ -1,186 +0,0 @@ -#!/bin/bash -set -e - -# Source environment variables for defaults and domain settings -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -if [ -f "$SCRIPT_DIR/../load-env.sh" ]; then - source "$SCRIPT_DIR/../load-env.sh" -fi - -# Default values -SERVICE_TYPE="" -SERVICE_NAME="" -NAMESPACE="" -IMAGE="" -PORT="" -SERVICE_DOMAIN="" -OUTPUT_DIR="" - -function show_help { - echo "Usage: $0 --type [public|internal|database|microservice] --name SERVICE_NAME [options]" - echo "" - echo "Required arguments:" - echo " --type TYPE Service type (public, internal, database, or microservice)" - echo " --name NAME Service name" - echo "" - echo "Optional arguments:" - echo " --namespace NAMESPACE Kubernetes namespace (defaults to service name)" - echo " --image IMAGE Container image (defaults to nginx:latest for most types)" - echo " --port PORT Container port (defaults to 80)" - echo " --domain DOMAIN Custom domain (defaults to TYPE-specific domain)" - echo " --output DIR Output directory (defaults to services/NAME)" - echo " --help Show this help message" - echo "" - echo "Examples:" - echo " $0 --type public --name blog" - echo " $0 --type internal --name admin --image my-admin:v1 --port 8080" - echo " $0 --type database --name mysql --image mysql:8.0 --port 3306" - echo " $0 --type microservice --name auth --image auth-service:v1 --port 9000" - exit 1 -} - -while [[ $# -gt 0 ]]; do - key="$1" - case $key in - --type) - SERVICE_TYPE="$2" - shift 2 - ;; - --name) - SERVICE_NAME="$2" - shift 2 - ;; - --namespace) - NAMESPACE="$2" - shift 2 - ;; - --image) - IMAGE="$2" - shift 2 - ;; - --port) - PORT="$2" - shift 2 - ;; - --domain) - SERVICE_DOMAIN="$2" - shift 2 - ;; - --output) - OUTPUT_DIR="$2" - shift 2 - ;; - --help) - show_help - ;; - *) - echo "Unknown option: $1" - show_help - ;; - esac -done - -# Validate required parameters -if [[ -z "$SERVICE_TYPE" ]]; then - echo "Error: Service type is required" - show_help -fi - -if [[ -z "$SERVICE_NAME" ]]; then - echo "Error: Service name is required" - show_help -fi - -# Validate service type -if [[ "$SERVICE_TYPE" != "public" && "$SERVICE_TYPE" != "internal" && "$SERVICE_TYPE" != "database" && "$SERVICE_TYPE" != "microservice" ]]; then - echo "Error: Invalid service type. Must be public, internal, database, or microservice." - show_help -fi - -# Set defaults -if [[ -z "$NAMESPACE" ]]; then - NAMESPACE="$SERVICE_NAME" -fi - -if [[ -z "$IMAGE" ]]; then - if [[ "$SERVICE_TYPE" == "database" ]]; then - IMAGE="mariadb:10.6" - else - IMAGE="nginx:latest" - fi -fi - -if [[ -z "$PORT" ]]; then - if [[ "$SERVICE_TYPE" == "database" ]]; then - PORT="3306" - else - PORT="80" - fi -fi - -if [[ -z "$SERVICE_DOMAIN" ]]; then - if [[ "$SERVICE_TYPE" == "public" ]]; then - SERVICE_DOMAIN="\${SERVICE_NAME}.\${DOMAIN}" - elif [[ "$SERVICE_TYPE" == "internal" ]]; then - SERVICE_DOMAIN="\${SERVICE_NAME}.internal.\${DOMAIN}" - elif [[ "$SERVICE_TYPE" == "microservice" ]]; then - SERVICE_DOMAIN="\${SERVICE_NAME}.svc.\${DOMAIN}" - else - SERVICE_DOMAIN="\${SERVICE_NAME}.db.\${DOMAIN}" - fi -fi - -# Set default output directory if not provided -if [[ -z "$OUTPUT_DIR" ]]; then - OUTPUT_DIR="$SCRIPT_DIR/../services/$SERVICE_NAME" -fi - -echo "Generating $SERVICE_TYPE service configuration for: $SERVICE_NAME" -echo "Namespace: $NAMESPACE" -echo "Image: $IMAGE" -echo "Port: $PORT" -echo "Domain Template: $SERVICE_DOMAIN" -echo "Output Directory: $OUTPUT_DIR" -echo - -# Get the appropriate template -if [[ "$SERVICE_TYPE" == "microservice" ]]; then - TEMPLATE_FILE="$SCRIPT_DIR/../services/templates/microservice/service.yaml" -else - TEMPLATE_FILE="$SCRIPT_DIR/../services/templates/${SERVICE_TYPE}-service/service.yaml" -fi - -if [[ ! -f "$TEMPLATE_FILE" ]]; then - echo "Error: Template file not found: $TEMPLATE_FILE" - exit 1 -fi - -# Create output directory if it doesn't exist -mkdir -p "$OUTPUT_DIR" - -# Create the service YAML -echo "Creating service configuration..." - -# Prepare variables for substitution -export SERVICE_NAME="$SERVICE_NAME" -export SERVICE_NAMESPACE="$NAMESPACE" -export SERVICE_IMAGE="\"$IMAGE\"" -export SERVICE_PORT="$PORT" -export SERVICE_DOMAIN="$SERVICE_DOMAIN" - -# Process the template with variable substitution -mkdir -p "$OUTPUT_DIR" - -# Define which variables to replace - only those from command arguments -VARS_TO_REPLACE='${SERVICE_NAME},${SERVICE_NAMESPACE},${SERVICE_IMAGE},${SERVICE_PORT},${SERVICE_DOMAIN}' - -# Process the template, only substituting the variables from arguments -cat "$TEMPLATE_FILE" | envsubst "$VARS_TO_REPLACE" > "$OUTPUT_DIR/service.yaml" - -echo "✅ Service configuration generated successfully!" -echo "Configuration file: $OUTPUT_DIR/service.yaml" -echo "" -echo "To deploy this service configuration:" -echo " ./bin/deploy-service $SERVICE_NAME" -echo "" -echo "To customize further, edit the generated file before deployment."