# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Default values for dynamo-operator.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

# Namespace restriction configuration for the operator
# If enabled: true and targetNamespace is empty, the operator will be restricted to the release namespace
# If enabled: true and targetNamespace is set, the operator will be restricted to the specified namespace
# If enabled: false, the operator will run with cluster-wide permissions
namespaceRestriction:
  # Whether to restrict the operator to a single namespace
  enabled: false
  # The target namespace to restrict to. If empty, defaults to the release namespace
  targetNamespace: ""
  # Namespace scope marker lease configuration (used to prevent conflicts when running both cluster-wide and namespace-restricted operators)
  lease:
    # Duration before the namespace scope marker lease expires if not renewed (namespace-restricted mode only). When a namespace-restricted operator is running, it creates a lease in its namespace. The cluster-wide operator detects this lease and excludes that namespace from processing. If the namespace operator stops renewing the lease (e.g., crashes), the lease expires and the cluster-wide operator automatically resumes processing that namespace.
    duration: 30s
    # Interval for renewing the namespace scope marker lease (namespace-restricted mode only). The namespace-restricted operator renews its lease at this interval to signal it's still running.
    renewInterval: 10s
controllerManager:
  tolerations: []
  affinity: {}

  # Leader election configuration
  leaderElection:
    # Leader election ID for cluster-wide coordination
    # WARNING: All cluster-wide operators must use the SAME ID to prevent split-brain
    # Different IDs would allow multiple leaders simultaneously
    id: ""  # If empty, defaults to: dynamo.nvidia.com (shared across all cluster-wide operators)

    # Namespace for leader election leases (only used in cluster-wide mode)
    # If empty, defaults to kube-system for cluster-wide coordination
    # All cluster-wide operators should use the SAME namespace for proper leader election
    namespace: ""

  kubeRbacProxy:
    args:
    - --secure-listen-address=0.0.0.0:8443
    - --upstream=http://127.0.0.1:8080/
    - --logtostderr=true
    - --v=0
    - --ignore-paths=/metrics
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
    image:
      repository: gcr.io/kubebuilder/kube-rbac-proxy
      tag: v0.15.0
    resources:
      limits:
        cpu: 500m
        memory: 128Mi
      requests:
        cpu: 5m
        memory: 64Mi
  manager:
    args:
    - --health-probe-bind-address=:8081
    - --metrics-bind-address=127.0.0.1:8080
    - --leader-elect
    - --leader-election-id=dynamo.nvidia.com
    containerSecurityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
    image:
      repository: nvcr.io/nvidia/ai-dynamo/kubernetes-operator
      # tag is optional - if not set, will use Chart.AppVersion
      tag: ""
    resources:
      limits:
        cpu: 1024m
        memory: 2Gi
      requests:
        cpu: 512m
        memory: 1Gi
  replicas: 1
  serviceAccount:
    annotations: {}

dynamo:
  components:
    serviceAccount:
      annotations: {}

  groveTerminationDelay: 15m

  internalImages:
    debugger: python:3.12-slim

  enableRestrictedSecurityContext: false

  dockerRegistry:
    server: ''
    # set to true if you want to use the kubernetes secret for the registry credentials
    # if false, no secret will be created and used. Allows to use cloud provider mechanisms for authentication (e.g. Workload Identity for GKE, ...)
    useKubernetesSecret: false
    username: '$oauthtoken'
    password: ""
    existingSecretName: ''
    secure: true

  metrics:
    prometheusEndpoint: ""

  mpiRun:
    secretName: "mpi-run-ssh-secret"
    sshKeygen:
      enabled: true


#imagePullSecrets: []
kubernetesClusterDomain: cluster.local
metricsService:
  enabled: true
  ports:
  - name: https
    port: 8443
    protocol: TCP
    targetPort: https
  type: ClusterIP

natsAddr: ""
etcdAddr: ""

nats:
  # Whether the NATS is enabled
  enabled: true

modelExpressURL: ""

# Checkpoint configuration for fast pod restore
# NOTE: The checkpoint infrastructure (PVC + DaemonSet) must be installed separately
# using the chrek Helm chart in each namespace where checkpointing is needed.
checkpoint:
  # Enable checkpoint/restore functionality
  enabled: false

  # Image used for init containers in checkpoint jobs (e.g., signal file cleanup)
  # Defaults to busybox:latest if not specified
  initContainerImage: "busybox:latest"

  # Storage configuration
  # These settings tell the operator where to find checkpoint storage
  # Must match the configuration in the chrek chart
  storage:
    # Storage backend type: pvc, s3, or oci
    type: pvc

    # Host path for signal files (communication between checkpoint pod and DaemonSet)
    signalHostPath: "/var/lib/chrek/signals"

    # PVC configuration (used when type=pvc)
    pvc:
      # Name of the PVC created by the chrek chart
      # Must match the PVC name in the chrek chart
      pvcName: "chrek-pvc"
      # Base path within the PVC for storing checkpoints
      basePath: "/checkpoints"

    # S3 configuration (used when type=s3)
    s3:
      # S3 URI in format: s3://[endpoint/]bucket/prefix
      # Examples:
      #   - s3://my-bucket/checkpoints (AWS S3)
      #   - s3://minio.example.com/my-bucket/checkpoints (MinIO/custom endpoint)
      uri: ""
      # Reference to a secret containing AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and optionally AWS_REGION
      # If not provided, uses IRSA/Workload Identity for authentication
      credentialsSecretRef: ""

    # OCI registry configuration (used when type=oci)
    oci:
      # OCI URI in format: oci://registry/repository
      # Examples:
      #   - oci://myregistry.io/checkpoints
      #   - oci://ghcr.io/myorg/checkpoints
      uri: ""
      # Reference to a docker config secret for registry authentication
      credentialsSecretRef: ""

  # CRIU timeout configuration (shared across checkpoint and restore)
  criu:
    # CRIU operation timeout in seconds
    # Maximum time to wait for checkpoint/restore to complete
    # Increase for models with very large memory footprints
    # 21600s (6 hours) is recommended for large LLMs (70B+)
    timeout: "21600"

# Webhook configuration
webhook:
  # Enable admission webhooks for validation
  # Enabled by default for production-ready validation and better error reporting
  enabled: true

  # Certificate configuration
  certificateSecret:
    # Name of the secret containing webhook TLS certificates
    # The secret must contain: tls.crt, tls.key, and ca.crt
    name: webhook-server-cert

    # Set to true if you're managing the certificate secret externally
    # When false (default), certificates are auto-generated via Helm hooks
    external: false

  # Certificate validity duration (in days) for auto-generated certificates
  # Only used when certManager.enabled=false and certificateSecret.external=false
  certificateValidity: 365

  # Container image for certificate generation and CA injection jobs
  # Only used when certManager.enabled=false and certificateSecret.external=false
  certGenerator:
    image:
      repository: bitnami/kubectl
      tag: latest
      pullPolicy: IfNotPresent

  # CA bundle for webhook (base64 encoded)
  # Only used when certificateSecret.external=true
  # For automatic mode or cert-manager, leave empty
  caBundle: ""

  # Webhook failure policy
  # Fail: Reject requests if webhook is unavailable (recommended for production)
  # Ignore: Allow requests if webhook is unavailable
  failurePolicy: Fail

  # Timeout for webhook calls (in seconds)
  timeoutSeconds: 10

  # Namespace selector for webhooks
  # Use this to exclude certain namespaces from validation
  #
  # For CLUSTER-WIDE operators: Exclude namespaces with namespace-restricted operators
  # namespaceSelector:
  #   matchExpressions:
  #   - key: dynamo-operator
  #     operator: NotIn
  #     values: ["namespace-restricted"]
  #
  # For NAMESPACE-RESTRICTED operators: Leave empty (auto-configured)
  namespaceSelector: {}

  # cert-manager integration (optional)
  certManager:
    # Enable cert-manager for automatic certificate management
    # Requires cert-manager to be installed in the cluster
    # When enabled, disables automatic certificate generation
    enabled: false

    # Certificate configuration for cert-manager
    certificate:
      # Certificate duration (e.g., "8760h" for 1 year)
      duration: "8760h"

      # Time before expiration to renew certificate (e.g., "360h" for 15 days)
      renewBefore: "360h"

      # Root CA configuration
      rootCA:
        # Duration for root CA certificate (e.g., "87600h" for 10 years)
        duration: "87600h"

        # Time before expiration to renew root CA (e.g., "720h" for 30 days)
        renewBefore: "720h"

