---
to: generated/deployment/{{name}}.yaml
vars:
  name: "user-deployment"
  description: "Kubernetes deployment configuration"
sparql:
  find_services: "SELECT ?service ?name ?port WHERE { ?service a ex:Microservice ; ex:name ?name ; ex:port ?port }"
  find_dependencies: "SELECT ?service ?dependency WHERE { ?service ex:hasDependencies ?dependency }"
freeze_policy: "checksum"
freeze_slots_dir: "generated/.ggen/freeze"
---

# {{description}}
# 
# Comprehensive Kubernetes deployment configuration including:
# - Multi-environment support (dev, staging, prod)
# - Resource management and scaling
# - Health checks and monitoring
# - Security policies and network policies
# - Backup and disaster recovery
# - CI/CD pipeline integration
#
# Generated by ggen on {{ "now" | date(format="%Y-%m-%d %H:%M:%S") }}

---
# Namespace
apiVersion: v1
kind: Namespace
metadata:
  name: {{name | replace(from="deployment", to="")}}
  labels:
    name: {{name | replace(from="deployment", to="")}}
    environment: production
    managed-by: ggen

---
# ConfigMap for application configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{name}}-config
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: config
data:
  # Application configuration
  APP_NAME: "comprehensive-rust-showcase"
  APP_VERSION: "1.0.0"
  LOG_LEVEL: "info"
  API_PORT: "3000"
  
  # Database configuration
  DATABASE_POOL_SIZE: "10"
  DATABASE_TIMEOUT_SECONDS: "30"
  DATABASE_MAX_CONNECTIONS: "100"
  
  # Cache configuration
  CACHE_TTL_SECONDS: "300"
  CACHE_MAX_SIZE_MB: "100"
  
  # Performance configuration
  MAX_REQUEST_SIZE_MB: "10"
  REQUEST_TIMEOUT_SECONDS: "30"
  RATE_LIMIT_REQUESTS: "1000"
  RATE_LIMIT_WINDOW_SECONDS: "60"
  
  # Security configuration
  JWT_EXPIRATION_HOURS: "24"
  PASSWORD_MIN_LENGTH: "8"
  SESSION_TIMEOUT_MINUTES: "30"
  
  # Monitoring configuration
  METRICS_ENABLED: "true"
  HEALTH_CHECK_INTERVAL_SECONDS: "30"
  PROFILING_ENABLED: "false"

---
# Secret for sensitive configuration
apiVersion: v1
kind: Secret
metadata:
  name: {{name}}-secrets
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: secrets
type: Opaque
data:
  # Base64 encoded secrets (replace with actual values)
  DATABASE_URL: cG9zdGdyZXNxbDovL3VzZXI6cGFzc3dvcmRAZGI6NTQzMi9kYg==
  REDIS_URL: cmVkaXM6Ly9yZWRpczozNjM3LzA=
  JWT_SECRET: c3VwZXItc2VjcmV0LWp3dC1rZXk=
  ENCRYPTION_KEY: c3VwZXItc2VjcmV0LWVuY3J5cHRpb24ta2V5
  
  # Database credentials
  DB_USERNAME: dXNlcg==
  DB_PASSWORD: cGFzc3dvcmQ=
  DB_HOST: ZGI=
  DB_PORT: NTQzMg==
  DB_NAME: ZGI=
  
  # Redis credentials
  REDIS_PASSWORD: cmVkaXMtcGFzc3dvcmQ=
  REDIS_HOST: cmVkaXM=
  REDIS_PORT: MzYzNw==

---
# Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{name}}-service-account
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: rbac
automountServiceAccountToken: true

---
# Role for service account
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: {{name}}-role
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: rbac
rules:
- apiGroups: [""]
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch"]

---
# RoleBinding for service account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: {{name}}-role-binding
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: rbac
subjects:
- kind: ServiceAccount
  name: {{name}}-service-account
  namespace: {{name | replace(from="deployment", to="")}}
roleRef:
  kind: Role
  name: {{name}}-role
  apiGroup: rbac.authorization.k8s.io

---
# PersistentVolumeClaim for data storage
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{name}}-data-pvc
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: storage
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: fast-ssd

---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{name}}
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: backend
    version: "1.0.0"
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  selector:
    matchLabels:
      app: {{name}}
  template:
    metadata:
      labels:
        app: {{name}}
        component: backend
        version: "1.0.0"
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "3000"
        prometheus.io/path: "/metrics"
    spec:
      serviceAccountName: {{name}}-service-account
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
      containers:
      - name: {{name}}
        image: comprehensive-rust-showcase:latest
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: 3000
          protocol: TCP
        - name: metrics
          containerPort: 9090
          protocol: TCP
        env:
        # Configuration from ConfigMap
        - name: APP_NAME
          valueFrom:
            configMapKeyRef:
              name: {{name}}-config
              key: APP_NAME
        - name: APP_VERSION
          valueFrom:
            configMapKeyRef:
              name: {{name}}-config
              key: APP_VERSION
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: {{name}}-config
              key: LOG_LEVEL
        - name: API_PORT
          valueFrom:
            configMapKeyRef:
              name: {{name}}-config
              key: API_PORT
        # Secrets
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: {{name}}-secrets
              key: DATABASE_URL
        - name: REDIS_URL
          valueFrom:
            secretKeyRef:
              name: {{name}}-secrets
              key: REDIS_URL
        - name: JWT_SECRET
          valueFrom:
            secretKeyRef:
              name: {{name}}-secrets
              key: JWT_SECRET
        - name: ENCRYPTION_KEY
          valueFrom:
            secretKeyRef:
              name: {{name}}-secrets
              key: ENCRYPTION_KEY
        # Resource limits and requests
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        # Health checks
        livenessProbe:
          httpGet:
            path: /health
            port: http
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
          successThreshold: 1
        readinessProbe:
          httpGet:
            path: /health
            port: http
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 3
          successThreshold: 1
        # Startup probe
        startupProbe:
          httpGet:
            path: /health
            port: http
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 30
          successThreshold: 1
        # Security context
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        # Volume mounts
        volumeMounts:
        - name: data-volume
          mountPath: /app/data
        - name: tmp-volume
          mountPath: /tmp
        - name: config-volume
          mountPath: /app/config
          readOnly: true
      # Volumes
      volumes:
      - name: data-volume
        persistentVolumeClaim:
          claimName: {{name}}-data-pvc
      - name: tmp-volume
        emptyDir: {}
      - name: config-volume
        configMap:
          name: {{name}}-config
      # Node selection
      nodeSelector:
        kubernetes.io/os: linux
        node-type: compute
      # Affinity rules
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - {{name}}
              topologyKey: kubernetes.io/hostname
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - database
            topologyKey: kubernetes.io/hostname
      # Tolerations
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"

---
# Service
apiVersion: v1
kind: Service
metadata:
  name: {{name}}-service
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: backend
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
  type: LoadBalancer
  ports:
  - name: http
    port: 80
    targetPort: http
    protocol: TCP
  - name: metrics
    port: 9090
    targetPort: metrics
    protocol: TCP
  selector:
    app: {{name}}
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{name}}-ingress
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "30"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "30"
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - api.example.com
    secretName: {{name}}-tls
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: {{name}}-service
            port:
              number: 80

---
# HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: {{name}}-hpa
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: autoscaling
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: {{name}}
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 60
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60

---
# PodDisruptionBudget
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: {{name}}-pdb
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: availability
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: {{name}}

---
# NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{name}}-network-policy
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: security
spec:
  podSelector:
    matchLabels:
      app: {{name}}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    - podSelector:
        matchLabels:
          app: {{name}}
    ports:
    - protocol: TCP
      port: 3000
    - protocol: TCP
      port: 9090
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432
  - to:
    - podSelector:
        matchLabels:
          app: redis
    ports:
    - protocol: TCP
      port: 6379
  - to: []
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 443

---
# ServiceMonitor for Prometheus
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: {{name}}-service-monitor
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: monitoring
spec:
  selector:
    matchLabels:
      app: {{name}}
  endpoints:
  - port: metrics
    path: /metrics
    interval: 30s
    scrapeTimeout: 10s

---
# PrometheusRule for alerting
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: {{name}}-prometheus-rules
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: monitoring
spec:
  groups:
  - name: {{name}}-rules
    rules:
    - alert: {{name | title}}Down
      expr: up{job="{{name}}"} == 0
      for: 1m
      labels:
        severity: critical
      annotations:
        summary: "{{name | title}} is down"
        description: "{{name | title}} has been down for more than 1 minute"
    
    - alert: {{name | title}}HighErrorRate
      expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
      for: 2m
      labels:
        severity: warning
      annotations:
        summary: "{{name | title}} high error rate"
        description: "{{name | title}} error rate is above 5% for more than 2 minutes"
    
    - alert: {{name | title}}HighResponseTime
      expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "{{name | title}} high response time"
        description: "{{name | title}} 95th percentile response time is above 1 second"
    
    - alert: {{name | title}}HighMemoryUsage
      expr: (container_memory_usage_bytes{container="{{name}}"} / container_spec_memory_limit_bytes{container="{{name}}"}) > 0.8
      for: 5m
      labels:
        severity: warning
      annotations:
        summary: "{{name | title}} high memory usage"
        description: "{{name | title}} memory usage is above 80%"

---
# CronJob for backup
apiVersion: batch/v1
kind: CronJob
metadata:
  name: {{name}}-backup-cronjob
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: backup
spec:
  schedule: "0 2 * * *"  # Daily at 2 AM
  concurrencyPolicy: Forbid
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: {{name}}-service-account
          containers:
          - name: backup
            image: postgres:15
            command:
            - /bin/bash
            - -c
            - |
              echo "Starting backup..."
              pg_dump $DATABASE_URL > /backup/backup-$(date +%Y%m%d-%H%M%S).sql
              echo "Backup completed"
            env:
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: {{name}}-secrets
                  key: DATABASE_URL
            volumeMounts:
            - name: backup-volume
              mountPath: /backup
          volumes:
          - name: backup-volume
            persistentVolumeClaim:
              claimName: {{name}}-backup-pvc
          restartPolicy: OnFailure

---
# PersistentVolumeClaim for backups
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{name}}-backup-pvc
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: backup
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: standard

---
# Job for database migration
apiVersion: batch/v1
kind: Job
metadata:
  name: {{name}}-migration-job
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: migration
spec:
  template:
    spec:
      serviceAccountName: {{name}}-service-account
      containers:
      - name: migration
        image: comprehensive-rust-showcase:latest
        command:
        - /app/migrate
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: {{name}}-secrets
              key: DATABASE_URL
        - name: MIGRATION_MODE
          value: "up"
      restartPolicy: Never
  backoffLimit: 3

---
# ConfigMap for environment-specific configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{name}}-env-config
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: config
data:
  # Environment-specific settings
  ENVIRONMENT: "production"
  DEBUG_MODE: "false"
  CORS_ORIGINS: "https://app.example.com,https://admin.example.com"
  
  # Feature flags
  FEATURE_NEW_API: "true"
  FEATURE_BETA_FEATURES: "false"
  FEATURE_ANALYTICS: "true"
  
  # External service URLs
  EXTERNAL_API_URL: "https://api.external.com"
  CDN_URL: "https://cdn.example.com"
  ASSETS_URL: "https://assets.example.com"

---
# Secret for environment-specific secrets
apiVersion: v1
kind: Secret
metadata:
  name: {{name}}-env-secrets
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: secrets
type: Opaque
data:
  # Environment-specific secrets
  EXTERNAL_API_KEY: ZXh0ZXJuYWwtYXBpLWtleQ==
  CDN_API_KEY: Y2RuLWFwaS1rZXk=
  ANALYTICS_KEY: YW5hbHl0aWNzLWtleQ==
  
  # Third-party service credentials
  SMTP_PASSWORD: c210LXBhc3N3b3Jk
  SMS_API_KEY: c21zLWFwaS1rZXk=
  PAYMENT_GATEWAY_KEY: cGF5bWVudC1nYXRld2F5LWtleQ==

---
# Service for internal communication
apiVersion: v1
kind: Service
metadata:
  name: {{name}}-internal-service
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: internal
spec:
  type: ClusterIP
  ports:
  - name: http
    port: 3000
    targetPort: http
    protocol: TCP
  selector:
    app: {{name}}

---
# Endpoints for external service discovery
apiVersion: v1
kind: Endpoints
metadata:
  name: {{name}}-external-endpoints
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: external
subsets:
- addresses:
  - ip: 192.168.1.100
  ports:
  - port: 5432
    name: postgres
- addresses:
  - ip: 192.168.1.101
  ports:
  - port: 6379
    name: redis

---
# Service for external endpoints
apiVersion: v1
kind: Service
metadata:
  name: {{name}}-external-service
  namespace: {{name | replace(from="deployment", to="")}}
  labels:
    app: {{name}}
    component: external
spec:
  type: ExternalName
  externalName: external-database.example.com
  ports:
  - port: 5432
    name: postgres
