diff --git a/apps/example-app/deployment.yaml b/apps/example-app/deployment.yaml new file mode 100644 index 0000000..260b824 --- /dev/null +++ b/apps/example-app/deployment.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: 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: 128Mi + requests: + cpu: 100m + memory: 32Mi + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/apps/example-app/ingress.yaml b/apps/example-app/ingress.yaml new file mode 100644 index 0000000..812bc0e --- /dev/null +++ b/apps/example-app/ingress.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: example-app + annotations: + external-dns.alpha.kubernetes.io/target: {{ (ds "config").cloud.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.{{ (ds "config").cloud.domain }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: example-app + port: + number: 80 + tls: + - hosts: + - example-app.{{ (ds "config").cloud.domain }} + secretName: wildcard-wild-cloud-tls diff --git a/apps/example-app/kustomization.yaml b/apps/example-app/kustomization.yaml new file mode 100644 index 0000000..e3c2881 --- /dev/null +++ b/apps/example-app/kustomization.yaml @@ -0,0 +1,14 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: example-app +labels: + - includeSelectors: true + pairs: + app: example-app + managedBy: kustomize + partOf: wild-cloud +resources: + - deployment.yaml + - ingress.yaml + - namespace.yaml + - service.yaml diff --git a/apps/example-app/manifest.yaml b/apps/example-app/manifest.yaml new file mode 100644 index 0000000..14ef366 --- /dev/null +++ b/apps/example-app/manifest.yaml @@ -0,0 +1,4 @@ +name: example-app +install: true +description: An example application that is deployed with public access. +version: 1.0.0 diff --git a/apps/example-app/namespace.yaml b/apps/example-app/namespace.yaml new file mode 100644 index 0000000..3ddeaab --- /dev/null +++ b/apps/example-app/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: example-app diff --git a/apps/example-app/service.yaml b/apps/example-app/service.yaml index cc6be05..f3c826a 100644 --- a/apps/example-app/service.yaml +++ b/apps/example-app/service.yaml @@ -1,57 +1,8 @@ --- -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 @@ -59,35 +10,3 @@ spec: - 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/bin/wild-app-add b/bin/wild-app-add new file mode 100755 index 0000000..e7a9cbe --- /dev/null +++ b/bin/wild-app-add @@ -0,0 +1,90 @@ +#!/bin/bash + +set -e +set -o pipefail + +if [ $# -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +APP_NAME="$1" + +if [ ! -d ".wildcloud" ]; then + echo "Error: .wildcloud directory not found in current directory" + echo "This script must be run from a directory that contains a .wildcloud directory" + exit 1 +fi + +if [ ! -f ".wildcloud/config.yaml" ]; then + echo "Error: .wildcloud/config.yaml not found" + exit 1 +fi + +WILDCLOUD_REPO=$(yq eval '.wildcloud.repository' .wildcloud/config.yaml) + +if [ -z "${WILDCLOUD_REPO}" ] || [ "${WILDCLOUD_REPO}" = "null" ]; then + echo "Error: wildcloud.config not found in .wildcloud/config.yaml" + exit 1 +fi + +SOURCE_APP_DIR="${WILDCLOUD_REPO}/apps/${APP_NAME}" +if [ ! -d "${SOURCE_APP_DIR}" ]; then + echo "Error: App '${APP_NAME}' not found at ${SOURCE_APP_DIR}" + exit 1 +fi + +DEST_APP_DIR="apps/${APP_NAME}" +mkdir -p "apps" + +if [ -d "${DEST_APP_DIR}" ]; then + echo "Warning: Destination directory ${DEST_APP_DIR} already exists" + read -p "Do you want to overwrite it? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Installation cancelled" + exit 1 + fi + rm -rf "${DEST_APP_DIR}" +fi + +echo "Copying app '${APP_NAME}' from ${SOURCE_APP_DIR} to ${DEST_APP_DIR}" + +# Function to process a file with gomplate if it's a YAML file +process_file() { + local src_file="$1" + local dest_file="$2" + + if [[ "${src_file}" == *.yaml ]] || [[ "${src_file}" == *.yml ]]; then + echo "Processing YAML file: ${dest_file}" + gomplate -d config=.wildcloud/config.yaml -f "${src_file}" > "${dest_file}" + else + cp "${src_file}" "${dest_file}" + fi +} + +# Create destination directory +mkdir -p "${DEST_APP_DIR}" + +# Copy directory structure and process files +find "${SOURCE_APP_DIR}" -type d | while read -r src_dir; do + rel_path="${src_dir#${SOURCE_APP_DIR}}" + rel_path="${rel_path#/}" # Remove leading slash if present + if [ -n "${rel_path}" ]; then + mkdir -p "${DEST_APP_DIR}/${rel_path}" + fi +done + +find "${SOURCE_APP_DIR}" -type f | while read -r src_file; do + rel_path="${src_file#${SOURCE_APP_DIR}}" + rel_path="${rel_path#/}" # Remove leading slash if present + dest_file="${DEST_APP_DIR}/${rel_path}" + + # Ensure destination directory exists + dest_dir=$(dirname "${dest_file}") + mkdir -p "${dest_dir}" + + process_file "${src_file}" "${dest_file}" +done + +echo "Successfully installed app '${APP_NAME}' with template processing" \ No newline at end of file diff --git a/bin/wild-app-install b/bin/wild-app-install new file mode 100755 index 0000000..2a355f1 --- /dev/null +++ b/bin/wild-app-install @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +if [ $# -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +APP_NAME="$1" + +kubectl apply -k "apps/${APP_NAME}"