# Sandbox deployment template — variables are populated from the user's License k8sResources.
# Variables: {{userId}}, {{deploymentName}}, {{pvcName}}, {{serviceName}},
#            {{sandboxImage}}, {{sidecarImage}}, {{imagePullPolicy}}, {{storageClass}},
#            {{serviceNamespace}}, {{licenseType}},
#            {{memoryRequest}}, {{memoryLimit}}, {{cpuRequest}}, {{cpuLimit}},
#            {{storage}}, {{tmpSizeLimit}},
#            {{enableIdleShutdown}}, {{idleTimeoutMinutes}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{deploymentName}}
  labels:
    app.kubernetes.io/name: sandbox
    app.kubernetes.io/component: user-sandbox
    dexorder.io/component: sandbox
    dexorder.io/user-id: {{userId}}
    dexorder.io/deployment: {{deploymentName}}
    dexorder.io/license-tier: {{licenseType}}
spec:
  replicas: 1
  selector:
    matchLabels:
      dexorder.io/user-id: {{userId}}
  template:
    metadata:
      labels:
        dexorder.io/component: sandbox
        dexorder.io/user-id: {{userId}}
        dexorder.io/deployment: {{deploymentName}}
        dexorder.io/license-tier: {{licenseType}}
    spec:
      serviceAccountName: sandbox-lifecycle
      shareProcessNamespace: true

      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
        seccompProfile:
          type: RuntimeDefault

      containers:
        - name: sandbox
          image: {{sandboxImage}}
          imagePullPolicy: {{imagePullPolicy}}

          securityContext:
            allowPrivilegeEscalation: false
            runAsNonRoot: true
            runAsUser: 1000
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL

          resources:
            requests:
              memory: "{{memoryRequest}}"
              cpu: "{{cpuRequest}}"
            limits:
              memory: "{{memoryLimit}}"
              cpu: "{{cpuLimit}}"

          env:
            - name: USER_ID
              value: {{userId}}
            - name: IDLE_TIMEOUT_MINUTES
              value: "{{idleTimeoutMinutes}}"
            - name: IDLE_CHECK_INTERVAL_SECONDS
              value: "60"
            - name: ENABLE_IDLE_SHUTDOWN
              value: "{{enableIdleShutdown}}"
            - name: MCP_SERVER_PORT
              value: "3000"
            - name: ZMQ_CONTROL_PORT
              value: "5555"
            - name: ZMQ_GATEWAY_ENDPOINT
              value: "tcp://gateway.{{serviceNamespace}}.svc.cluster.local:5571"
            - name: ICEBERG_CATALOG_URI
              value: "http://iceberg-catalog.{{serviceNamespace}}.svc.cluster.local:8181"
            - name: ICEBERG_NAMESPACE
              value: "trading"
            - name: S3_ENDPOINT
              value: "http://minio.{{serviceNamespace}}.svc.cluster.local:9000"
            - name: RELAY_ENDPOINT
              value: "tcp://relay.{{serviceNamespace}}.svc.cluster.local:5559"

          ports:
            - name: mcp
              containerPort: 3000
              protocol: TCP
            - name: zmq-control
              containerPort: 5555
              protocol: TCP

          volumeMounts:
            - name: sandbox-data
              mountPath: /app/data
            - name: sandbox-config
              mountPath: /app/config
              readOnly: true
            - name: tmp
              mountPath: /tmp
            - name: shared-run
              mountPath: /var/run/sandbox

          livenessProbe:
            httpGet:
              path: /health
              port: mcp
            initialDelaySeconds: 10
            periodSeconds: 30
            timeoutSeconds: 5

          readinessProbe:
            httpGet:
              path: /health
              port: mcp
            initialDelaySeconds: 5
            periodSeconds: 10

        - name: lifecycle-sidecar
          image: {{sidecarImage}}
          imagePullPolicy: {{imagePullPolicy}}

          securityContext:
            allowPrivilegeEscalation: false
            runAsNonRoot: true
            runAsUser: 1000
            readOnlyRootFilesystem: true
            capabilities:
              drop:
                - ALL

          resources:
            requests:
              memory: "32Mi"
              cpu: "10m"
            limits:
              memory: "64Mi"
              cpu: "50m"

          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: DEPLOYMENT_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['dexorder.io/deployment']
            - name: USER_TYPE
              value: "{{licenseType}}"
            - name: MAIN_CONTAINER_PID
              value: "1"

          volumeMounts:
            - name: shared-run
              mountPath: /var/run/sandbox
              readOnly: true

      volumes:
        - name: sandbox-data
          persistentVolumeClaim:
            claimName: {{pvcName}}
        - name: sandbox-config
          projected:
            sources:
              - configMap:
                  name: sandbox-config
              - secret:
                  name: sandbox-secrets
        - name: tmp
          emptyDir:
            medium: Memory
            sizeLimit: {{tmpSizeLimit}}
        - name: shared-run
          emptyDir:
            medium: Memory
            sizeLimit: 1Mi

      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{pvcName}}
  labels:
    dexorder.io/user-id: {{userId}}
    dexorder.io/license-tier: {{licenseType}}
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: {{storage}}
  storageClassName: {{storageClass}}
---
apiVersion: v1
kind: Service
metadata:
  name: {{serviceName}}
  labels:
    dexorder.io/user-id: {{userId}}
    dexorder.io/license-tier: {{licenseType}}
spec:
  type: ClusterIP
  selector:
    dexorder.io/user-id: {{userId}}
  ports:
    - name: mcp
      port: 3000
      targetPort: mcp
      protocol: TCP
    - name: zmq-control
      port: 5555
      targetPort: zmq-control
      protocol: TCP
