apiVersion: apps/v1
kind: Deployment
metadata:
  name: dapr-operator
  namespace: {{ .Release.Namespace }}
  labels:
    app: dapr-operator
    {{- range $key, $value := .Values.global.k8sLabels }}
    {{ $key }}: {{ tpl $value $ }}
    {{- end }}
spec:
{{- if eq .Values.global.ha.enabled true }}
  replicas: {{ .Values.global.ha.replicaCount }}
{{- else }}
  replicas: {{ .Values.replicaCount }}
{{- end }}
  selector:
    matchLabels:
      app: dapr-operator
  template:
    metadata:
      labels:
        app: dapr-operator
        {{- range $key, $value := .Values.global.k8sLabels }}
        {{ $key }}: {{ tpl $value $ }}
        {{- end }}
        {{- with .Values.global.labels }}
          {{- toYaml . | nindent 8 }}
        {{- end }}
      annotations:
        dapr.io/control-plane: operator
{{- if eq .Values.global.prometheus.enabled true }}
        prometheus.io/scrape: "{{ .Values.global.prometheus.enabled }}"
        prometheus.io/port: "{{ .Values.global.prometheus.port }}"
        prometheus.io/path: "/"
{{- end }}
{{- with .Values.deploymentAnnotations }}
{{ toYaml . | indent 8 }}
{{- end }}
    spec:
      containers:
      - name: dapr-operator
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
{{- if eq .Values.debug.enabled false }}
          initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }}
{{- else }}
          initialDelaySeconds: {{ .Values.debug.initialDelaySeconds }}
{{- end }}
          periodSeconds: {{ .Values.livenessProbe.periodSeconds }}
          failureThreshold: {{ .Values.livenessProbe.failureThreshold }}
        readinessProbe:
          httpGet:
            path: /healthz
            port: 8080
{{- if eq .Values.debug.enabled false }}
          initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }}
{{- else }}
          initialDelaySeconds: {{ .Values.debug.initialDelaySeconds }}
{{- end }}
          periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
          failureThreshold: {{ .Values.readinessProbe.failureThreshold }}
{{- if contains "/" .Values.image.name }}
        image: "{{ .Values.image.name }}"
{{- else }}
        image: "{{ .Values.global.registry }}/{{ .Values.image.name }}:{{ .Values.global.tag }}"
{{- end }}
        imagePullPolicy: {{ .Values.global.imagePullPolicy }}
{{- if eq .Values.global.daprControlPlaneOs "linux" }}
        securityContext:
          runAsNonRoot: {{ .Values.runAsNonRoot }}
  {{- if eq .Values.debug.enabled true }}
          capabilities:
            add: ["SYS_PTRACE"]
  {{- else }}
          readOnlyRootFilesystem: true
          capabilities:
            drop: ["ALL"]
  {{- end }}
  {{- if .Values.global.seccompProfile }}
          seccompProfile:
            type: {{ .Values.global.seccompProfile }}
  {{- end }}
{{- end }}
        env:
        - name: NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        {{- range $name, $value := .Values.extraEnvVars }}
        - name: "{{ $name }}"
          value: "{{ $value }}"
        {{- end }}
        ports:
        - containerPort: 6500
{{- if eq .Values.global.prometheus.enabled true }}
        - name: metrics
          containerPort: {{ .Values.global.prometheus.port }}
          protocol: TCP
{{- end }}
{{- if eq .Values.debug.enabled true }}
        - name: debug
          containerPort: {{ .Values.debug.port }}
          protocol: TCP
{{- end }}
        resources:
{{ toYaml .Values.resources | indent 10 }}
        volumeMounts:
        - name: dapr-trust-bundle
          mountPath: /var/run/secrets/dapr.io/tls
          readOnly: true
      {{- if .Values.global.mtls.mountSentryVolume }}
        - name: dapr-identity-token
          mountPath: /var/run/secrets/dapr.io/sentrytoken
          readOnly: true
      {{- end }}
      {{- if eq .Values.debug.enabled false }}
        # This is not needed in debug mode because the root FS is writable
        - name: dapr-operator-tmp
          mountPath: /tmp
      {{- end }}
      {{- with .Values.global.extraVolumeMounts.operator }}
        {{- toYaml . | nindent 8 }}
      {{- end }}
        command:
{{- if eq .Values.debug.enabled false }}
        - "/operator"
{{- else }}
        - "/dlv"
{{- end }}
        args:
{{- if eq .Values.debug.enabled true }}
        - "--listen=:{{ .Values.debug.port }}"
        - "--accept-multiclient"
        - "--headless=true"
        - "--log"
        - "--api-version=2"
        - "exec"
        - "/operator"
        - "--"
{{- end }}
        - "--watch-interval"
        - "{{ .Values.watchInterval }}"
        - "--max-pod-restarts-per-minute"
        - "{{ .Values.maxPodRestartsPerMinute }}"
        - "--log-level"
        - "{{ .Values.logLevel }}"
        - "--trust-anchors-file"
        - "/var/run/secrets/dapr.io/tls/ca.crt"
{{- if eq .Values.global.logAsJson true }}
        - "--log-as-json"
{{- end }}
{{- if eq .Values.global.prometheus.enabled true }}
        - "--enable-metrics"
        - "--metrics-port"
        - "{{ .Values.global.prometheus.port }}"
{{- else }}
        - "--enable-metrics=false"
{{- end }}
{{- if .Values.watchNamespace }}
        - "--watch-namespace"
        - "{{ .Values.watchNamespace }}"
{{- end }}
{{- if not .Values.serviceReconciler.enabled }}
        - "--disable-service-reconciler"
{{- end }}
{{- if .Values.global.argoRolloutServiceReconciler.enabled }}
        - "--enable-argo-rollout-service-reconciler"
{{- end }}
{{- if .Values.global.operator.watchdogCanPatchPodLabels }}
        - "--watchdog-can-patch-pod-labels"
{{- end }}
      serviceAccountName: dapr-operator
      volumes:
        - name: dapr-operator-tmp
          emptyDir:
            sizeLimit: 2Mi
            medium: Memory
        - name: dapr-trust-bundle
          configMap:
            name: dapr-trust-bundle
    {{- if .Values.global.mtls.mountSentryVolume }}
        - name: dapr-identity-token
          projected:
            sources:
            - serviceAccountToken:
                path: token
                expirationSeconds: 600
                audience: "spiffe://{{ .Values.global.mtls.controlPlaneTrustDomain }}/ns/{{ .Release.Namespace }}/dapr-sentry"
    {{- end }}
      {{- with .Values.global.extraVolumes.operator }}
        {{- toYaml . | nindent 8 }}
      {{- end }}
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
             nodeSelectorTerms:
                - matchExpressions:
                  - key: kubernetes.io/os
                    operator: In
                    values:
                    - {{ .Values.global.daprControlPlaneOs }}
{{- if .Values.global.daprControlPlaneArch }}
                  - key: kubernetes.io/arch
                    operator: In
                    values:
                    - {{ .Values.global.daprControlPlaneArch }}
{{- end }}
{{- if .Values.global.ha.enabled }}
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - dapr-operator
              topologyKey: topology.kubernetes.io/zone
{{- end }}
{{- if .Values.global.imagePullSecrets }}
      imagePullSecrets:
        {{- include "dapr.imagePullSecrets" (dict "imagePullSecrets" .Values.global.imagePullSecrets) | nindent 8 -}}
{{- end }}
{{- if .Values.global.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.global.nodeSelector | indent 8 }}
{{- end }}
{{- if .Values.global.tolerations }}
      tolerations:
{{ toYaml .Values.global.tolerations | indent 8 }}
{{- end }}
{{- if .Values.global.priorityClassName }}
      priorityClassName:
{{ toYaml .Values.global.priorityClassName | indent 8 }}
{{- end }}
