# 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.

{{/* Validate installation to prevent conflicts */}}
{{- include "dynamo-operator.validateClusterWideInstallation" . -}}
{{- include "dynamo-operator.validateConfiguration" . -}}
{{- include "dynamo-operator.validateDiscoveryBackend" . -}}

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "dynamo-operator.fullname" . }}-controller-manager
  labels:
    app.kubernetes.io/component: manager
    app.kubernetes.io/created-by: dynamo-operator
    app.kubernetes.io/part-of: dynamo-operator
    control-plane: controller-manager
  {{- include "dynamo-operator.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.controllerManager.replicas }}
  strategy:
    type: Recreate
  selector:
    matchLabels:
      control-plane: controller-manager
    {{- include "dynamo-operator.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        control-plane: controller-manager
      {{- include "dynamo-operator.selectorLabels" . | nindent 8 }}
      annotations:
        kubectl.kubernetes.io/default-container: manager
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.controllerManager.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.controllerManager.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      containers:
      - args: {{- toYaml .Values.controllerManager.kubeRbacProxy.args | nindent
          8 }}
        env:
        - name: KUBERNETES_CLUSTER_DOMAIN
          value: {{ quote .Values.kubernetesClusterDomain }}
        imagePullPolicy: {{ .Values.controllerManager.kubeRbacProxy.image.pullPolicy | quote }}
        image: {{ .Values.controllerManager.kubeRbacProxy.image.repository }}:{{
          .Values.controllerManager.kubeRbacProxy.image.tag | default .Chart.AppVersion
          }}
        name: kube-rbac-proxy
        ports:
        - containerPort: 8443
          name: https
          protocol: TCP
        resources: {{- toYaml .Values.controllerManager.kubeRbacProxy.resources
          | nindent 10 }}
        securityContext: {{- toYaml .Values.controllerManager.kubeRbacProxy.containerSecurityContext
          | nindent 10 }}
      - args:
        {{- range .Values.controllerManager.manager.args }}
          - {{ . }}
        {{- end }}
          - --leader-elect
          - --leader-election-id={{ default "dynamo.nvidia.com" .Values.controllerManager.leaderElection.id }}
        {{- if .Values.namespaceRestriction.enabled }}
          {{- $restrictedNs := default .Release.Namespace .Values.namespaceRestriction.targetNamespace }}
          - --restrictedNamespace={{ $restrictedNs }}
          - --leader-election-namespace={{ $restrictedNs }}
        {{- else }}
          - --leader-election-namespace={{ default "kube-system" .Values.controllerManager.leaderElection.namespace }}
        {{- end }}
        {{- if .Values.natsAddr }}
          - --natsAddr={{ .Values.natsAddr }}
        {{- else if and .Values.nats .Values.nats.enabled }}
          - --natsAddr=nats://{{ .Release.Name }}-nats.{{ .Release.Namespace }}.svc.cluster.local:4222
        {{- end }}
        {{- if .Values.etcdAddr }}
          - --etcdAddr={{ .Values.etcdAddr }}
        {{- else if and .Values.global .Values.global.etcd .Values.global.etcd.install }}
          - --etcdAddr={{ .Release.Name }}-etcd.{{ .Release.Namespace }}.svc.cluster.local:2379
        {{- end }}
        {{- if and .Values.dynamo.istio.enabled .Values.dynamo.istio.gateway }}
          - --istio-virtual-service-gateway={{ .Values.dynamo.istio.gateway }}
        {{- end }}
        {{- if .Values.dynamo.ingress.enabled }}
        {{- if  .Values.dynamo.ingress.className }}
          - --ingress-controller-class-name={{ .Values.dynamo.ingress.className }}
        {{- end }}
        {{- if  .Values.dynamo.ingress.tlsSecretName }}
          - --ingress-controller-tls-secret-name={{ .Values.dynamo.ingress.tlsSecretName }}
        {{- end }}
        {{- end }}
        {{- if .Values.dynamo.ingressHostSuffix }}
          - --ingress-host-suffix={{ .Values.dynamo.ingressHostSuffix }}
        {{- end }}
        {{- if .Values.dynamo.virtualServiceSupportsHTTPS }}
          - --virtual-service-supports-https={{ .Values.dynamo.virtualServiceSupportsHTTPS }}
        {{- end }}
        {{- if .Values.dynamo.groveTerminationDelay }}
          - --grove-termination-delay={{ .Values.dynamo.groveTerminationDelay }}
        {{- end }}
        {{- if .Values.modelExpressURL }}
          - --model-express-url={{ .Values.modelExpressURL }}
        {{- end }}
        {{- if .Values.dynamo.metrics.prometheusEndpoint }}
          - --prometheus-endpoint={{ .Values.dynamo.metrics.prometheusEndpoint }}
        {{- end }}
        {{- if .Values.dynamo.mpiRun.secretName }}
          - --mpi-run-ssh-secret-name={{ .Values.dynamo.mpiRun.secretName }}
          - --mpi-run-ssh-secret-namespace={{ .Release.Namespace }}
        {{- end }}
        {{- if not .Values.namespaceRestriction.enabled }}
          - --dgdr-profiling-cluster-role-name={{ include "dynamo-operator.fullname" . }}-dgdr-profiling
          - --planner-cluster-role-name={{ include "dynamo-operator.fullname" . }}-planner
          - --epp-cluster-role-name={{ include "dynamo-operator.fullname" . }}-epp
        {{- end }}
        {{- if .Values.discoveryBackend }}
          - --discovery-backend={{ .Values.discoveryBackend }}
        {{- end }}
        {{- if .Values.namespaceRestriction.enabled }}
        {{- if .Values.namespaceRestriction.lease }}
          - --namespace-scope-lease-duration={{ .Values.namespaceRestriction.lease.duration }}
          - --namespace-scope-lease-renew-interval={{ .Values.namespaceRestriction.lease.renewInterval }}
        {{- end }}
          - --gpu-discovery-enabled={{ .Values.gpuDiscovery.enabled }}
        {{- end }}
          - --operator-version={{ .Chart.AppVersion }}
        {{- if .Values.checkpoint.enabled }}
          - --checkpoint-enabled=true
          - --checkpoint-storage-type={{ .Values.checkpoint.storage.type }}
          - --checkpoint-ready-for-checkpoint-file-path={{ .Values.checkpoint.readyForCheckpointFilePath }}
          {{- if eq .Values.checkpoint.storage.type "pvc" }}
          - --checkpoint-pvc-name={{ .Values.checkpoint.storage.pvc.pvcName }}
          - --checkpoint-pvc-base-path={{ .Values.checkpoint.storage.pvc.basePath }}
          {{- end }}
          {{- if eq .Values.checkpoint.storage.type "s3" }}
          - --checkpoint-s3-uri={{ .Values.checkpoint.storage.s3.uri }}
          {{- if .Values.checkpoint.storage.s3.credentialsSecretRef }}
          - --checkpoint-s3-credentials-secret={{ .Values.checkpoint.storage.s3.credentialsSecretRef }}
          {{- end }}
          {{- end }}
          {{- if eq .Values.checkpoint.storage.type "oci" }}
          - --checkpoint-oci-uri={{ .Values.checkpoint.storage.oci.uri }}
          {{- if .Values.checkpoint.storage.oci.credentialsSecretRef }}
          - --checkpoint-oci-credentials-secret={{ .Values.checkpoint.storage.oci.credentialsSecretRef }}
          {{- end }}
          {{- end }}
        {{- end }}
        command:
        - /manager
        env:
        - name: KUBERNETES_CLUSTER_DOMAIN
          value: {{ quote .Values.kubernetesClusterDomain }}
        imagePullPolicy: {{ .Values.controllerManager.manager.image.pullPolicy | quote }}
        image: {{ .Values.controllerManager.manager.image.repository }}:{{ .Values.controllerManager.manager.image.tag
| default .Chart.AppVersion }}
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8081
          initialDelaySeconds: 15
          periodSeconds: 20
        name: manager
        ports:
        - containerPort: 9443
          name: webhook-server
          protocol: TCP
        readinessProbe:
          httpGet:
            path: /readyz
            port: 8081
          initialDelaySeconds: 5
          periodSeconds: 10
        resources: {{- toYaml .Values.controllerManager.manager.resources | nindent
          10 }}
        securityContext: {{- toYaml .Values.controllerManager.manager.containerSecurityContext
          | nindent 10 }}
        volumeMounts:
        - mountPath: /tmp/k8s-webhook-server/serving-certs
          name: cert
          readOnly: true
      securityContext:
        runAsNonRoot: true
      serviceAccountName: {{ include "dynamo-operator.fullname" . }}-controller-manager
      terminationGracePeriodSeconds: 30
      volumes:
      - name: cert
        secret:
          defaultMode: 420
          secretName: {{ .Values.webhook.certificateSecret.name }}
