---
# VAPORA Backup CronJobs
# Automated hourly database backups and daily config backups
# Uses scripts/backup/*.nu for backup execution

apiVersion: v1
kind: ServiceAccount
metadata:
  name: vapora-backup
  namespace: vapora

---
# RBAC for backup operations (read-only access to resources)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: vapora-backup-read
rules:
  - apiGroups: [""]
    resources:
      - configmaps
      - secrets
      - services
    verbs: ["get", "list"]
  - apiGroups: ["apps"]
    resources:
      - deployments
      - statefulsets
      - daemonsets
    verbs: ["get", "list"]
  - apiGroups: ["networking.k8s.io"]
    resources:
      - ingresses
    verbs: ["get", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: vapora-backup-read-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: vapora-backup-read
subjects:
  - kind: ServiceAccount
    name: vapora-backup
    namespace: vapora

---
# Hourly S3 + Restic Database Backup
# Exports SurrealDB and backs up to both S3 and Restic
apiVersion: batch/v1
kind: CronJob
metadata:
  name: vapora-backup-database-hourly
  namespace: vapora
  labels:
    app: vapora
    component: backup
    schedule: hourly
spec:
  # Every hour at minute 0
  schedule: "0 * * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    metadata:
      labels:
        app: vapora
        backup-type: database
    spec:
      backoffLimit: 1
      activeDeadlineSeconds: 1800  # 30 minutes timeout
      template:
        metadata:
          labels:
            app: vapora
            job-type: backup
        spec:
          serviceAccountName: vapora-backup
          restartPolicy: Never
          containers:
            - name: backup
              image: ghcr.io/vapora/vapora-backup-tools:latest
              imagePullPolicy: IfNotPresent
              env:
                # SurrealDB connection
                - name: SURREAL_URL
                  value: "ws://surrealdb:8000"
                - name: SURREAL_USER
                  value: "root"
                - name: SURREAL_PASS
                  valueFrom:
                    secretKeyRef:
                      name: vapora-secrets
                      key: surreal_password

                # S3 Configuration
                - name: S3_BUCKET
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: backup_s3_bucket
                - name: S3_PREFIX
                  value: "backups/database"
                - name: AWS_REGION
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: aws_region

                # S3 Credentials
                - name: AWS_ACCESS_KEY_ID
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: access_key_id
                - name: AWS_SECRET_ACCESS_KEY
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: secret_access_key

                # Encryption
                - name: ENCRYPTION_KEY_PATH
                  value: "/etc/backup-keys/encryption.key"

                # Restic Configuration
                - name: RESTIC_REPO
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: restic_repo
                - name: RESTIC_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: vapora-secrets
                      key: restic_password

              volumeMounts:
                - name: encryption-key
                  mountPath: /etc/backup-keys
                  readOnly: true
                - name: backup-cache
                  mountPath: /tmp/backup

              # Resource limits for backup job
              resources:
                requests:
                  cpu: "500m"
                  memory: "512Mi"
                limits:
                  cpu: "2000m"
                  memory: "2Gi"

              # Run backup orchestrator
              command:
                - /bin/bash
                - -c
                - |
                  nu /scripts/orchestrate-backup-recovery.nu \
                    --operation backup \
                    --mode full \
                    --surreal-url "$SURREAL_URL" \
                    --surreal-user "$SURREAL_USER" \
                    --surreal-pass "$SURREAL_PASS" \
                    --s3-bucket "$S3_BUCKET" \
                    --s3-prefix "$S3_PREFIX" \
                    --encryption-key "$ENCRYPTION_KEY_PATH" \
                    --restic-repo "$RESTIC_REPO" \
                    --restic-password "$RESTIC_PASSWORD" \
                    --iac-dir "provisioning"

          volumes:
            - name: encryption-key
              secret:
                secretName: vapora-encryption-key
                defaultMode: 0400
            - name: backup-cache
              emptyDir:
                sizeLimit: 5Gi

---
# Daily Configuration Backup
# Backs up ConfigMaps, Secrets, and Deployments to S3 and Restic
apiVersion: batch/v1
kind: CronJob
metadata:
  name: vapora-backup-config-daily
  namespace: vapora
  labels:
    app: vapora
    component: backup
    schedule: daily
spec:
  # Every day at 02:00 UTC
  schedule: "0 2 * * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    metadata:
      labels:
        app: vapora
        backup-type: config
    spec:
      backoffLimit: 1
      activeDeadlineSeconds: 3600  # 60 minutes timeout
      template:
        metadata:
          labels:
            app: vapora
            job-type: backup
        spec:
          serviceAccountName: vapora-backup
          restartPolicy: Never
          containers:
            - name: backup
              image: ghcr.io/vapora/vapora-backup-tools:latest
              imagePullPolicy: IfNotPresent
              env:
                - name: NAMESPACE
                  value: "vapora"
                - name: S3_BUCKET
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: backup_s3_bucket
                - name: S3_PREFIX
                  value: "backups/config"
                - name: AWS_REGION
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: aws_region
                - name: AWS_ACCESS_KEY_ID
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: access_key_id
                - name: AWS_SECRET_ACCESS_KEY
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: secret_access_key

              volumeMounts:
                - name: backup-cache
                  mountPath: /tmp/backup

              resources:
                requests:
                  cpu: "250m"
                  memory: "256Mi"
                limits:
                  cpu: "1000m"
                  memory: "1Gi"

              command:
                - /bin/bash
                - -c
                - |
                  nu /scripts/backup/config-backup.nu \
                    --namespace "$NAMESPACE" \
                    --s3-bucket "$S3_BUCKET" \
                    --s3-prefix "$S3_PREFIX"

          volumes:
            - name: backup-cache
              emptyDir:
                sizeLimit: 2Gi

---
# Daily Backup Health Verification
# Checks backup integrity and freshness
apiVersion: batch/v1
kind: CronJob
metadata:
  name: vapora-backup-health-check
  namespace: vapora
  labels:
    app: vapora
    component: backup
    schedule: daily
spec:
  # Every day at 03:00 UTC
  schedule: "0 3 * * *"
  concurrencyPolicy: Replace
  successfulJobsHistoryLimit: 7
  failedJobsHistoryLimit: 7
  jobTemplate:
    metadata:
      labels:
        app: vapora
        job-type: health-check
    spec:
      backoffLimit: 0
      activeDeadlineSeconds: 900  # 15 minutes timeout
      template:
        metadata:
          labels:
            app: vapora
            job-type: backup-verification
        spec:
          serviceAccountName: vapora-backup
          restartPolicy: Never
          containers:
            - name: verify
              image: ghcr.io/vapora/vapora-backup-tools:latest
              imagePullPolicy: IfNotPresent
              env:
                - name: S3_BUCKET
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: backup_s3_bucket
                - name: RESTIC_REPO
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: restic_repo
                - name: RESTIC_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: vapora-secrets
                      key: restic_password
                - name: SURREAL_URL
                  value: "ws://surrealdb:8000"
                - name: SURREAL_USER
                  value: "root"
                - name: SURREAL_PASS
                  valueFrom:
                    secretKeyRef:
                      name: vapora-secrets
                      key: surreal_password
                - name: AWS_REGION
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: aws_region
                - name: AWS_ACCESS_KEY_ID
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: access_key_id
                - name: AWS_SECRET_ACCESS_KEY
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: secret_access_key

              resources:
                requests:
                  cpu: "200m"
                  memory: "256Mi"
                limits:
                  cpu: "500m"
                  memory: "512Mi"

              command:
                - /bin/bash
                - -c
                - |
                  nu /scripts/verify-backup-health.nu \
                    --s3-bucket "$S3_BUCKET" \
                    --s3-prefix "backups/database" \
                    --restic-repo "$RESTIC_REPO" \
                    --restic-password "$RESTIC_PASSWORD" \
                    --surreal-url "$SURREAL_URL" \
                    --surreal-user "$SURREAL_USER" \
                    --surreal-pass "$SURREAL_PASS" \
                    --max-age-hours 25

---
# Monthly Backup Rotation
# Cleans up old snapshots and archives to cold storage
apiVersion: batch/v1
kind: CronJob
metadata:
  name: vapora-backup-rotation-monthly
  namespace: vapora
  labels:
    app: vapora
    component: backup
    schedule: monthly
spec:
  # First day of month at 04:00 UTC
  schedule: "0 4 1 * *"
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 3
  jobTemplate:
    metadata:
      labels:
        app: vapora
        job-type: rotation
    spec:
      backoffLimit: 1
      activeDeadlineSeconds: 3600
      template:
        metadata:
          labels:
            app: vapora
            job-type: backup-rotation
        spec:
          serviceAccountName: vapora-backup
          restartPolicy: Never
          containers:
            - name: rotation
              image: ghcr.io/vapora/vapora-backup-tools:latest
              imagePullPolicy: IfNotPresent
              env:
                - name: RESTIC_REPO
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: restic_repo
                - name: RESTIC_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: vapora-secrets
                      key: restic_password
                - name: S3_BUCKET
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: backup_s3_bucket
                - name: AWS_REGION
                  valueFrom:
                    configMapKeyRef:
                      name: vapora-config
                      key: aws_region
                - name: AWS_ACCESS_KEY_ID
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: access_key_id
                - name: AWS_SECRET_ACCESS_KEY
                  valueFrom:
                    secretKeyRef:
                      name: vapora-aws-credentials
                      key: secret_access_key

              resources:
                requests:
                  cpu: "200m"
                  memory: "256Mi"
                limits:
                  cpu: "1000m"
                  memory: "1Gi"

              command:
                - /bin/bash
                - -c
                - |
                  # Cleanup old Restic snapshots
                  RESTIC_PASSWORD="$RESTIC_PASSWORD" \
                  restic -r "$RESTIC_REPO" forget \
                    --keep-daily 7 \
                    --keep-weekly 4 \
                    --keep-monthly 12 \
                    --prune
