---
# Superset Secret
apiVersion: v1
kind: Secret
metadata:
  name: superset-secret
  namespace: tools
type: Opaque
stringData:
  SUPERSET_SECRET_KEY: "<SUPERSET_SECRET_KEY>"
  ADMIN_PASSWORD: "<SUPERSET_ADMIN_PASSWORD>"
  DATABASE_PASSWORD: "<SUPERSET_DATABASE_PASSWORD>"
  REDIS_PASSWORD: "<SUPERSET_REDIS_PASSWORD>"

---
# Superset Redis
apiVersion: apps/v1
kind: Deployment
metadata:
  name: superset-redis
  namespace: tools
spec:
  replicas: 1
  selector:
    matchLabels:
      app: superset-redis
  template:
    metadata:
      labels:
        app: superset-redis
    spec:
      containers:
        - name: redis
          image: redis:7-alpine
          ports:
            - containerPort: 6379
          resources:
            requests:
              memory: "64Mi"
              cpu: "50m"
            limits:
              memory: "256Mi"
              cpu: "200m"

---
apiVersion: v1
kind: Service
metadata:
  name: superset-redis
  namespace: tools
spec:
  selector:
    app: superset-redis
  ports:
    - port: 6379

---
# Superset PostgreSQL PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: superset-postgres-data
  namespace: tools
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: local-path

---
# Superset PostgreSQL
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: superset-postgres
  namespace: tools
spec:
  serviceName: superset-postgres
  replicas: 1
  selector:
    matchLabels:
      app: superset-postgres
  template:
    metadata:
      labels:
        app: superset-postgres
    spec:
      containers:
        - name: postgres
          image: postgres:15-alpine
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_USER
              value: "superset"
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: superset-secret
                  key: DATABASE_PASSWORD
            - name: POSTGRES_DB
              value: "superset"
          volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "500m"
      volumes:
        - name: postgres-data
          persistentVolumeClaim:
            claimName: superset-postgres-data

---
apiVersion: v1
kind: Service
metadata:
  name: superset-postgres
  namespace: tools
spec:
  selector:
    app: superset-postgres
  ports:
    - port: 5432
  clusterIP: None

---
# Superset ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: superset-config
  namespace: tools
data:
  superset_config.py: |
    import os

    # Basic Config
    SECRET_KEY = os.environ.get('SUPERSET_SECRET_KEY', 'your-secret-key')

    # Database
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')

    # Redis
    REDIS_HOST = os.environ.get('REDIS_HOST', 'superset-redis')
    REDIS_PORT = os.environ.get('REDIS_PORT', 6379)

    # Cache
    CACHE_CONFIG = {
        'CACHE_TYPE': 'RedisCache',
        'CACHE_DEFAULT_TIMEOUT': 300,
        'CACHE_KEY_PREFIX': 'superset_',
        'CACHE_REDIS_HOST': REDIS_HOST,
        'CACHE_REDIS_PORT': REDIS_PORT,
    }

    # Celery
    class CeleryConfig:
        broker_url = f'redis://{REDIS_HOST}:{REDIS_PORT}/0'
        result_backend = f'redis://{REDIS_HOST}:{REDIS_PORT}/1'

    CELERY_CONFIG = CeleryConfig

    # Language
    BABEL_DEFAULT_LOCALE = 'zh_Hant_TW'

    # Proxy fix for reverse proxy
    ENABLE_PROXY_FIX = True
    PROXY_FIX_CONFIG = {
        "x_for": 1,
        "x_proto": 1,
        "x_host": 1,
        "x_prefix": 0,
    }

---
# Superset Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: superset
  namespace: tools
  labels:
    app: superset
spec:
  replicas: 1
  selector:
    matchLabels:
      app: superset
  template:
    metadata:
      labels:
        app: superset
    spec:
      initContainers:
        - name: superset-init
          image: apache/superset:3.1.1
          command: ["/bin/sh", "-c"]
          args:
            - |
              pip install psycopg2-binary &&
              superset db upgrade &&
              superset fab create-admin --username admin --firstname Admin --lastname User --email admin@wooo.work --password $ADMIN_PASSWORD || true &&
              superset init
          env:
            - name: SUPERSET_SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: superset-secret
                  key: SUPERSET_SECRET_KEY
            - name: ADMIN_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: superset-secret
                  key: ADMIN_PASSWORD
            - name: DATABASE_URL
              value: "postgresql+psycopg2://superset:<SUPERSET_DATABASE_PASSWORD>@superset-postgres:5432/superset"
          volumeMounts:
            - name: superset-config
              mountPath: /app/pythonpath/superset_config.py
              subPath: superset_config.py
      containers:
        - name: superset
          image: apache/superset:3.1.1
          command: ["/bin/sh", "-c"]
          args:
            - |
              pip install psycopg2-binary &&
              gunicorn --bind 0.0.0.0:8088 --workers 2 --timeout 120 "superset.app:create_app()"
          ports:
            - containerPort: 8088
          env:
            - name: SUPERSET_SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: superset-secret
                  key: SUPERSET_SECRET_KEY
            - name: DATABASE_URL
              value: "postgresql+psycopg2://superset:<SUPERSET_DATABASE_PASSWORD>@superset-postgres:5432/superset"
            - name: REDIS_HOST
              value: "superset-redis"
          volumeMounts:
            - name: superset-config
              mountPath: /app/pythonpath/superset_config.py
              subPath: superset_config.py
          resources:
            requests:
              memory: "512Mi"
              cpu: "200m"
            limits:
              memory: "2Gi"
              cpu: "1000m"
          livenessProbe:
            httpGet:
              path: /health
              port: 8088
            initialDelaySeconds: 180
            periodSeconds: 30
            timeoutSeconds: 10
          readinessProbe:
            httpGet:
              path: /health
              port: 8088
            initialDelaySeconds: 120
            periodSeconds: 10
            timeoutSeconds: 5
      volumes:
        - name: superset-config
          configMap:
            name: superset-config

---
# Superset Service
apiVersion: v1
kind: Service
metadata:
  name: superset
  namespace: tools
spec:
  selector:
    app: superset
  ports:
    - port: 8088
      targetPort: 8088
  type: ClusterIP
