{{- $apiVersions := (include "k8s.apiVersions" .) | fromJson }}
{{- $primaryCluster := (eq (include "aws.eksPrimaryClusters" .) "true") }}
{{- $fullName := (include "k8s.serviceFullname" .) }}
{{- $svcName := (include "k8s.serviceName" .) }}
{{- $labels := (include "k8s.labels" .) | fromJson }}
{{- $selectorLabels := (include "k8s.selectorLabels" .) | fromJson }}
{{- $ddLabels := (include "datadog.labels" .) | fromJson }}
{{- $dockerImagePullPolicy := .Values.image.pullPolicy | default (include "docker.imagePullPolicy" .) }}
{{- $dockerImageTag := .Values.image.tag }}
{{- $containerPortName := .Values.service.port.name | default "http" }}
{{- $appPort := (.Values.service.port.targetPort | default .Values.service.port.servicePort ) | default .Values.app.port }}
{{- $hcPort := .Values.service.healthcheck.targetPort | default .Values.service.healthcheck.servicePort }}
{{- $secretName := (include "k8s.secretName" .) }}
{{- $configMapVolumeName := (include "k8s.configMapVolumeName" .) }}
{{- $chartAppVersion := .Chart.AppVersion }}
{{- $kubeVersion := .Capabilities.KubeVersion.GitVersion }}
{{- $seaLightsDisabled := .Values.app.seaLights.disabled | default false }}
{{- $seaLightsForceMode := .Values.app.seaLights.forceMode | default 0 }}
{{- if eq .Values.cluster.environment "prd" }}
{{- $seaLightsDisabled = true }}
{{- end }}
{{- $secrets := "" }}
{{- $secretsVolumeMountEnabled := false }}
{{- if .Values.externalSecrets.enabled }}
{{- $secrets = "envs" }}
{{- if .Values.externalSecrets.secret.useSecretRef }}
{{- $secrets = "reference" }}
{{- end }}
{{- if .Values.externalSecrets.secret.volumeMount.enabled }}
{{- $secretsVolumeMountEnabled = true }}
{{- end }}
{{- end }}
{{- $otlpMetricsEnabled := .Values.otlpMetrics.enabled | default false }}
{{- $otlpPort := "4318" }}
{{- if eq .Values.otlpMetrics.protocol "grpc" }}
{{- $otlpPort = "4317" }}
{{- end }}
{{- $dsruDefaults := (include "k8s.deploymentStrategyRollingUpdateDefaults" .) | fromJson }}
{{- $nodeAffinitiyOperator := .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.operator | default "DoesNotExist" }}
{{- if (eq (include "k8s.deploymentEnabled" .) "true") }}
{{- $deploymentStrategyType := "RollingUpdate" }}
{{- if eq .Values.deployment.deploymentStrategy.type "Recreate" }}
{{- $deploymentStrategyType = "Recreate" }}
{{- end }}
---
apiVersion: {{ get $apiVersions "Deployment" }}
kind: Deployment
metadata:
  name: {{ $fullName }}
  namespace: {{ .Release.Namespace }}
  labels:
  {{- range $key, $value := $labels }}
    {{ $key }}: {{ $value }}
  {{- end }}
  {{- range $key, $value := $ddLabels }}
    {{ $key }}: {{ $value }}
  {{- end }}
  annotations:
  {{- if and .Values.harnessCanaryDisabled (or (ne .Values.cluster.environment "preprd") (ne .Values.cluster.environment "prd")) }}
    harness.io/direct-apply: "true"
  {{- end }}
  {{- with .Values.deployment.annotations }}
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
{{- if (eq (include "k8s.autoscalingEnabled" .) "false") }}
  replicas: {{ .Values.replicaCount }}
{{- end }}
  strategy:
    type: {{ $deploymentStrategyType }}
  {{- if eq $deploymentStrategyType "RollingUpdate" }}
    rollingUpdate:
      maxSurge: {{ .Values.deployment.rollingUpdate.maxSurge | default (.Values.deployment.deploymentStrategy.maxSurge | default (get $dsruDefaults "maxSurge")) }}
      maxUnavailable: {{ .Values.deployment.rollingUpdate.maxUnavailable | default (.Values.deployment.deploymentStrategy.maxUnavailable | default (get $dsruDefaults "maxUnavailable")) }}
  {{- end }}
  selector:
    matchLabels:
    {{- range $key, $value := $selectorLabels }}
      {{ $key }}: {{ $value }}
    {{- end }}
  template:
    metadata:
      annotations:
      {{- if .Values.app.prometheus.enabled }}
        prometheus.io/path: {{ .Values.app.prometheus.path | quote }}
        prometheus.io/port: {{ .Values.app.prometheus.port | quote }}
        prometheus.io/scrape: {{ .Values.app.prometheus.scrape | quote }}
      {{- end }}
      {{- with .Values.pod.annotations }}
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- if (eq (include "istio.enabled" .) "true") }}
        sidecar.istio.io/inject: "true"
        {{- if .Values.istio.security.envoyFilter.ratelimit.enabled }}
        proxy.istio.io/config: |-
          holdApplicationUntilProxyStarts: true
          proxyStatsMatcher:
            inclusionRegexps:
            - ".*http_local_rate_limit.*"
        {{- else }}
        proxy.istio.io/config: {{ .Values.istio.proxyConfig | toJson | quote }}
        {{- end }}
      {{- end }}
      {{- if and (not .Values.istio.forceDisabled) .Values.istio.bootstrapConfig }}
        sidecar.istio.io/bootstrapOverride: {{ include "istio.bootstrapConfigMapName" . | quote }}
      {{- end }}
      labels:
      {{- range $key, $value := $labels }}
        {{ $key }}: {{ $value }}
      {{- end }}
      {{- range $key, $value := $ddLabels }}
        {{ $key }}: {{ $value }}
      {{- end }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "k8s.serviceAccountName" . }}
    {{- if .Values.pod.securityContext }}
      securityContext:
        {{- toYaml .Values.pod.securityContext | nindent 8 }}
    {{- end }}
      terminationGracePeriodSeconds: {{ .Values.pod.terminationGracePeriodSeconds | default 120 }}
    {{- if not (empty .Values.pod.topologySpreadConstraints) }}
      topologySpreadConstraints:
      {{- range $tsc := .Values.pod.topologySpreadConstraints }}
        - maxSkew: {{ $tsc.maxSkew | default 1 }}
          topologyKey: {{ $tsc.topologyKey | default "topology.kubernetes.io/zone" }}
          whenUnsatisfiable: {{ $tsc.whenUnsatisfiable | default "DoNotSchedule" }}
          labelSelector:
            matchLabels:
            {{- if $tsc.labelSelector }}
              {{- toYaml $tsc.labelSelector | nindent 14 }}
            {{- else }}
              {{- range $key, $value := $selectorLabels }}
              {{ $key }}: {{ $value }}
              {{- end }}
            {{- end }}
        {{- if and $tsc.minDomains (semverCompare ">=1.24-0" $kubeVersion) }}
          minDomains: {{ $tsc.minDomains }}
        {{- end }}
        {{- if and $tsc.matchLabelKeys (semverCompare ">=1.25-0" $kubeVersion) }}
          matchLabelKeys: {{ $tsc.matchLabelKeys }}
        {{- end }}
        {{- if and $tsc.nodeAffinityPolicy (semverCompare ">=1.25-0" $kubeVersion) }}
          nodeAffinityPolicy: {{ $tsc.nodeAffinityPolicy }}
        {{- end }}
        {{- if and $tsc.nodeTaintsPolicy (semverCompare ">=1.25-0" $kubeVersion) }}
          nodeTaintsPolicy: {{ $tsc.nodeTaintsPolicy }}
        {{- end }}
      {{- end }}
    {{- end }}
      containers:
        - name: {{ $svcName }}
        {{- if .Values.pod.lifecycle }}
          lifecycle:
            {{- toYaml .Values.pod.lifecycle | nindent 12 }}
        {{- end }}
          image: {{ include "docker.imageURI" . | quote }}
          imagePullPolicy: {{ $dockerImagePullPolicy }}
        {{- if .Values.pod.command }}
          command: {{ .Values.pod.command }}
          {{- if .Values.pod.args }}
          args:
          {{- range .Values.pod.args }}
            - {{ . | quote }}
          {{- end }}
          {{- end }}
        {{- end }}
          ports:
            - name: {{ $containerPortName }}
              containerPort: {{ $appPort }}
              protocol: {{ .Values.service.port.protocol | default "TCP" }}
          {{- if and $hcPort (ne (int $hcPort) (int $appPort)) }}
            - name: healthcheck
              containerPort: {{ $hcPort }}
              protocol: {{ .Values.service.healthcheck.protocol | default "TCP" }}
          {{- end }}
          {{- if and .Values.app.prometheus.enabled (ne (int .Values.app.prometheus.port) (int $appPort)) }}
            - name: metrics
              containerPort: {{ .Values.app.prometheus.port }}
              protocol: TCP
          {{- end }}
          {{- if .Values.service.ports }}
            {{- $targetPortList := list }}
          {{- range $port := .Values.service.ports }}
            {{- $targetPort := $port.targetPort }}
          {{- if and $targetPort (ne (int $targetPort) (int $appPort)) (ne (int $targetPort) (int $hcPort)) }}
            {{- $targetPortList = append $targetPortList $targetPort }}
            {{- $portName := $port.name | required "service.ports[].name required!" }}
            - containerPort: {{ $targetPort }}
              protocol: {{ $port.protocol | default "TCP" }}
              name: {{ $portName }}
          {{- end }}
          {{- end }}
          {{- end }}
          livenessProbe:
          {{- if .Values.pod.livenessProbe.useTCPSocket }}
            tcpSocket:
            {{- if .Values.service.healthcheck.servicePort }}
              port: healthcheck
            {{- else }}
              port: {{ $containerPortName }}
            {{- end }}
          {{- else if .Values.pod.livenessProbe.useEXEC }}
            exec:
              command:
              {{- if .Values.pod.livenessProbe.customCommand }}
                {{- toYaml .Values.pod.livenessProbe.customCommand |nindent 16 }}
              {{- else }}
                - /bin/bash
                - -c
                - {{ .Values.pod.livenessProbe.command }}
              {{- end }}
          {{- else if and .Values.pod.livenessProbe.useGRPC (semverCompare ">=1.23-0" $kubeVersion) }}
            grpc:
              port: {{ $appPort }}
          {{- else }}
            httpGet:
              path: {{ include "k8s.serviceLivenessProbePath" . }}
            {{- if .Values.service.healthcheck.servicePort }}
              port: healthcheck
            {{- else }}
              port: {{ $containerPortName }}
            {{- end }}
          {{- end }}
            initialDelaySeconds: {{ .Values.pod.livenessProbe.initialDelaySeconds | default 5 }}
            periodSeconds: {{ .Values.pod.livenessProbe.periodSeconds | default 10 }}
            timeoutSeconds: {{ .Values.pod.livenessProbe.timeoutSeconds | default 1 }}
            successThreshold: {{ .Values.pod.livenessProbe.successThreshold | default 1 }}
            failureThreshold: {{ .Values.pod.livenessProbe.failureThreshold | default 3 }}
          readinessProbe:
          {{- if .Values.pod.readinessProbe.useTCPSocket }}
            tcpSocket:
            {{- if .Values.service.healthcheck.servicePort }}
              port: healthcheck
            {{- else }}
              port: {{ $containerPortName }}
            {{- end }}
          {{- else if .Values.pod.readinessProbe.useEXEC }}
            exec:
              command:
              {{- if .Values.pod.readinessProbe.customCommand }}
                {{- toYaml .Values.pod.readinessProbe.customCommand |nindent 16 }}
              {{- else }}
                - /bin/bash
                - -c
                - {{ .Values.pod.readinessProbe.command }}
              {{- end }}
          {{- else if and .Values.pod.readinessProbe.useGRPC (semverCompare ">=1.23-0" $kubeVersion) }}
            grpc:
              port: {{ $appPort }}
          {{- else }}
            httpGet:
              path: {{ include "k8s.serviceReadinessProbePath" . }}
            {{- if .Values.service.healthcheck.servicePort }}
              port: healthcheck
            {{- else }}
              port: {{ $containerPortName }}
            {{- end }}
          {{- end }}
            initialDelaySeconds: {{ .Values.pod.readinessProbe.initialDelaySeconds | default 5 }}
            periodSeconds: {{ .Values.pod.readinessProbe.periodSeconds | default 10 }}
            timeoutSeconds: {{ .Values.pod.readinessProbe.timeoutSeconds | default 1 }}
            successThreshold: {{ .Values.pod.readinessProbe.successThreshold | default 1 }}
            failureThreshold: {{ .Values.pod.readinessProbe.failureThreshold | default 3 }}
          env:
          {{- with .Values.deployment.customEnvVars }}
            {{- toYaml . | nindent 12 }}
          {{- end }}
          {{- if or $primaryCluster (eq .Values.cluster.environment "dev") }}
            - name: DD_ENV
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['tags.datadoghq.com/env']
            - name: DD_SERVICE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['tags.datadoghq.com/service']
            - name: DD_VERSION
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['tags.datadoghq.com/version']
          {{- end }}
          {{- if $otlpMetricsEnabled }}
            - name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
              value: {{ cat "http://$(DD_AGENT_HOST):" $otlpPort "/v1/metrics" | nospace }}
            - name: OTEL_RESOURCE_ATTRIBUTES
              value: >-
                metric_protocol=otlp,
                version={{ $dockerImageTag | default $chartAppVersion }},
                service={{ $fullName }},
                service.version={{ $dockerImageTag | default $chartAppVersion }},
                service.namespace={{ .Release.Namespace }},
                kube_namespace={{ .Release.Namespace }}
            - name: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
              value: "delta"
            - name: OTEL_METRIC_EXPORT_INTERVAL
              value: {{ .Values.otlpMetrics.exportInterval | default "10000" | quote }}
          {{- end }}
            - name: PLUTO_APP_ENV
              value: {{ (include "service.appEnv" .) | quote }}
            - name: PLUTO_APP_HOSTNAME
              value: {{ (include "service.hostname" .) | quote }}
            - name: PLUTO_DOCKER_IMAGE_TAG
              value: {{ .Values.image.tag | default $chartAppVersion | quote }}
            - name: PLUTO_KVETCH_CHART_VERSION
              value: {{ (include "k8s.chartName" .) | quote }}
            - name: PLUTO_K8S_CLUSTER
              value: {{ (include "aws.eksClusterName" .) | quote }}
            - name: PLUTO_K8S_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: PLUTO_K8S_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
          {{- if $primaryCluster }}
            - name: PLUTO_OPENTELEMETRY_ENDPOINT
              value: {{ (include "open-telemetry.endpoint" .) | quote }}
          {{- end }}
            - name: SEALIGHTS_LAB_ID
              value: {{ $.Values.app.seaLights.labId | default (include "service.hostname" .) | quote }}
            - name: {{ eq (include "service.runtime" .) "node" | ternary "SL_LOG_LEVEL" "SEALIGHTS_LOG_LEVEL" }}
              value: {{ .Values.app.seaLights.logLevel | default "fatal" | quote }}
            - name: SEALIGHTS_DISABLE
              value: {{ $seaLightsDisabled | quote }}
            - name: SEALIGHTS_FORCE_MODE
              value: {{ $seaLightsForceMode | quote }}
            - name: VAULT_ADDR
              value: {{ (include "external-secrets.secretStoreAddress" .) | quote }}
          {{- if and (eq $secrets "envs") .Values.externalSecrets.secret.secretVariables }}
          {{- range $item := .Values.externalSecrets.secret.secretVariables }}
            - name: {{ $item.secretKey | replace "." "_" | replace "-" "_" | upper }}
              valueFrom:
                secretKeyRef:
                  name: {{ $secretName }}
                  key: {{ $item.secretKey }}
          {{- end }}
          {{- end }}
          {{- if .Values.debugCharts | default false }}
            - name: CLUSTER_ENABLED
              value: {{ (include "aws.eksClusterEnabled" .) | quote }}
            - name: PRIMARY_CLUSTER
              value: {{ (include "aws.eksPrimaryClusters" .) | quote }}
            - name: ISTIO_ENABLED
              value: {{ (include "istio.enabled" .) | quote }}
            - name: AUTOSCALING_ENABLED
              value: {{ (include "k8s.autoscalingEnabled" .) | quote }}
            - name: MOCK_ENABLED
              value: {{ (include "service.mockEnabled" .) | quote }}
          {{- end }}
          {{- if or .Values.configMap.environmentVariables (eq $secrets "reference") }}
          envFrom:
          {{- if (eq $secrets "reference") }}
            - secretRef:
                name: {{ $secretName }}
          {{- end }}
          {{- if .Values.configMap.environmentVariables }}
            - configMapRef:
                name: {{ include "k8s.configMapName" . }}
          {{- end }}
          {{- end }}
          {{- with .Values.resources }}
          resources:
            {{- toYaml . | nindent 12 }}
          {{- end }}
          {{- if or .Values.deployment.volumeMounts .Values.deployment.configVolumeMounts.enabled $secretsVolumeMountEnabled }}
          volumeMounts:
          {{- with .Values.deployment.volumeMounts }}
            {{- toYaml . | nindent 12 }}
          {{- end }}
          {{- if .Values.deployment.configVolumeMounts.enabled }}
            - mountPath: {{ include "k8s.configMapVolumeMountPath" . }}
              name: {{ $configMapVolumeName | replace "." "-" }}-volume
          {{- end }}
          {{- if $secretsVolumeMountEnabled }}
            - mountPath: {{ .Values.externalSecrets.secret.volumeMount.mountPath | default (cat ($secretName | replace "." "-") "/" | nospace) }}
              name: {{ $secretName | replace "." "-" }}-volume
              readOnly: true
          {{- end }}
          {{- end }}
      {{- if .Values.deployment.dnsConfig }}
      dnsConfig: {{- toYaml .Values.deployment.dnsConfig | nindent 8 }}
      {{- end }}
      {{- if .Values.deployment.dnsPolicy }}
      dnsPolicy: {{ .Values.deployment.dnsPolicy | quote }}
      {{- end }}
      {{- if or .Values.deployment.volumes (not (empty .Values.persistence.volumeClaims)) .Values.deployment.configVolumeMounts.enabled $secretsVolumeMountEnabled }}
      volumes:
      {{- with .Values.deployment.volumes }}
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- if not (empty .Values.persistence.volumeClaims) }}
      {{- range $pvc := .Values.persistence.volumeClaims }}
        - name: {{ cat "persistent-storage-" $pvc.name |nospace }}
          persistentVolumeClaim:
            claimName: pvc.{{ $fullName }}-{{ $pvc.name }}
      {{- end }}
      {{- end }}
      {{- if .Values.deployment.configVolumeMounts.enabled }}
        - name: {{ $configMapVolumeName | replace "." "-" }}-volume
          configMap:
            name: {{ $configMapVolumeName }}
            items:
              - key: {{ .Values.deployment.configVolumeMounts.volumeKeyOverride | default "config" }}
                path: {{ .Values.deployment.configVolumeMounts.volumePathOverride | default (include "k8s.configFile" .) }}
      {{- end }}
      {{- if $secretsVolumeMountEnabled }}
        - name: {{ $secretName | replace "." "-" }}-volume
          secret:
            secretName: {{ $secretName }}
          {{- with .Values.externalSecrets.secret.volumeMount.items }}
            items:
            {{- toYaml . | nindent 14 }}
          {{- end }}
      {{- end }}
      {{- end }}
      {{- with .Values.node.selector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      affinity:
      {{- with .Values.node.affinity.podAffinity }}
        podAffinity:
          {{- toYaml . | nindent 10 }}
      {{- end }}
      {{- with .Values.node.affinity.podAntiAffinity }}
        podAntiAffinity:
          {{- toYaml . | nindent 10 }}
      {{- end }}
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: pluto.tv/service-dedicated-group
                  operator: {{ $nodeAffinitiyOperator | quote }}
                {{- if or (eq $nodeAffinitiyOperator "In") (eq $nodeAffinitiyOperator "NotIn") }}
                  {{- if not .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.values }}
                    {{- fail "error: node affinity serviceDedicatedGroup values required!" }}
                  {{- end }}
                  values:
                  {{- toYaml .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.values | nindent 18 }}
                {{- end }}
            {{- with .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.additionalMatchExpressions }}
              {{- toYaml . | nindent 16 }}
            {{- end }}
          {{- with .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms }}
            {{- toYaml . | nindent 14 }}
          {{- end }}
        {{- with .Values.node.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution }}
          preferredDuringSchedulingIgnoredDuringExecution:
          {{- toYaml . | nindent 10 }}
        {{- end }}
    {{- with .Values.node.tolerations }}
      tolerations:
      {{- toYaml . | nindent 6 }}
    {{- end }}

{{- if and .Values.deployment.overprovisioning.priorityClass (eq (include "k8s.autoscalingEnabled" .) "true") }}
---
apiVersion: {{ get $apiVersions "Deployment" }}
kind: Deployment
metadata:
  name: {{ include "k8s.deploymentOverprovisioningName" . }}
  annotations:
    harness.io/direct-apply: "true"
spec:
  replicas: 1
  selector:
    matchLabels:
      run: {{ include "k8s.deploymentOverprovisioningName" . }}
  template:
    metadata:
      labels:
        run: {{ include "k8s.deploymentOverprovisioningName" . }}
    spec:
      priorityClassName: {{ .Values.deployment.overprovisioning.priorityClass }}
      containers:
        - name: reserve-resources
          image: k8s.gcr.io/pause
          resources:
            requests:
              cpu: {{ .Values.deployment.overprovisioning.containers.resources.requests.cpu | default "1" | quote }}
              memory: {{ .Values.deployment.overprovisioning.containers.resources.requests.memory | default "2Gi" | quote }}
      {{- with .Values.node.selector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      affinity:
      {{- with .Values.node.affinity.podAffinity }}
        podAffinity:
          {{- toYaml . | nindent 10 }}
      {{- end }}
      {{- with .Values.node.affinity.podAntiAffinity }}
        podAntiAffinity:
          {{- toYaml . | nindent 10 }}
      {{- end }}
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: pluto.tv/service-dedicated-group
                  operator: {{ $nodeAffinitiyOperator | quote }}
                {{- if or (eq $nodeAffinitiyOperator "In") (eq $nodeAffinitiyOperator "NotIn") }}
                  {{- if not .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.values }}
                    {{- fail "error: node affinity serviceDedicatedGroup values required!" }}
                  {{- end }}
                  values:
                  {{- toYaml .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.values | nindent 18 }}
                {{- end }}
            {{- with .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.additionalMatchExpressions }}
              {{- toYaml . | nindent 16 }}
            {{- end }}
          {{- with .Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms }}
            {{- toYaml . | nindent 14 }}
          {{- end }}
        {{- with .Values.node.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution }}
          preferredDuringSchedulingIgnoredDuringExecution:
          {{- toYaml . | nindent 10 }}
        {{- end }}
    {{- with .Values.node.tolerations }}
      tolerations:
      {{- toYaml . | nindent 6 }}
    {{- end }}
{{- end }}
{{- end }}

{{- if .Values.worker.workers }}
{{- $svcName := (include "k8s.serviceName" .) }}
{{- range $worker := .Values.worker.workers }}
{{- $workerDeploymentStrategyType := "RollingUpdate" }}
{{- if eq (($worker.deployment).deploymentStrategy).type "Recreate" }}
{{- $workerDeploymentStrategyType = "Recreate" }}
{{- end }}
{{- $workerName := (cat ($worker.name | required "Worker name required!") "-worker" | nospace) }}
{{- $otlpMetricsWorkerEnabled := ($worker.otlpMetrics).enabled | default false }}
{{- $dockerWorkerImageTag := ((($worker.image).tag | default $dockerImageTag) | default $chartAppVersion) }}
---
apiVersion: {{ get $apiVersions "Deployment" }}
kind: Deployment
metadata:
  name: {{ $fullName }}-{{ $workerName }}
  namespace: {{ $.Release.Namespace }}
  labels:
  {{- range $key, $value := $labels }}
    {{- if eq $key "app.kubernetes.io/component" }}
      {{- $value = "service-worker" }}
    {{- else if or (eq $key "app.kubernetes.io/name") (eq $key "app") }}
      {{- $value = (cat $svcName "-" $workerName | nospace) }}
    {{- end }}
    {{ $key }}: {{ $value }}
  {{- end }}
  {{- range $key, $value := $ddLabels }}
    {{ $key }}: {{ $value }}
  {{- end }}
  annotations:
    harness.io/direct-apply: "true"
  {{- with $worker.annotations }}
    {{- toYaml . | nindent 4 }}
  {{- end }}
spec:
{{- if not ($worker.autoscaling).enabled }}
  replicas: {{ $worker.replicaCount }}
{{- end }}
  strategy:
    type: {{ $workerDeploymentStrategyType }}
  {{- if eq $workerDeploymentStrategyType "RollingUpdate" }}
    rollingUpdate:
      maxSurge: {{ ($worker.rollingUpdate).maxSurge | default ((($worker.deployment).deploymentStrategy).maxSurge | default (get $dsruDefaults "maxSurge")) }}
      maxUnavailable: {{ ($worker.rollingUpdate).maxSurge | default ((($worker.deployment).deploymentStrategy).maxUnavailable | default (get $dsruDefaults "maxUnavailable")) }}
  {{- end }}
  selector:
    matchLabels:
    {{- range $key, $value := $selectorLabels }}
      {{- if eq $key "app.kubernetes.io/name" }}
        {{- $value = (cat $svcName "-" $workerName | nospace) }}
      {{- end }}
      {{ $key }}: {{ $value }}
    {{- end }}
  template:
    metadata:
      annotations:
      {{- with ($worker.pod).annotations }}
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- if (eq (include "istio.enabled" $) "true") }}
        sidecar.istio.io/inject: "true"
        proxy.istio.io/config: {{ $.Values.istio.proxyConfig | toJson | quote }}
      {{- end }}
      {{- if ($worker.prometheus).enabled }}
        prometheus.io/path: {{ $worker.prometheus.path | quote }}
        prometheus.io/port: {{ $worker.prometheus.port | quote }}
        prometheus.io/scrape: {{ $worker.prometheus.scrape | quote }}
      {{- end }}
      labels:
      {{- range $key, $value := $labels }}
        {{- if eq $key "app.kubernetes.io/name" }}
          {{- $value = (cat $svcName "-" $workerName | nospace) }}
        {{- end }}
        {{ $key }}: {{ $value }}
      {{- end }}
      {{- range $key, $value := $ddLabels }}
        {{ $key }}: {{ $value }}
      {{- end }}
    spec:
      {{- with $.Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "k8s.serviceAccountName" $ }}
    {{- if $.Values.pod.securityContext }}
      securityContext:
        {{- toYaml $.Values.pod.securityContext | nindent 8 }}
    {{- end }}
      terminationGracePeriodSeconds: {{ ($worker.pod).terminationGracePeriodSeconds | default 120 }}
    {{- if not (empty $.Values.pod.topologySpreadConstraints) }}
      topologySpreadConstraints:
      {{- range $tsc := $.Values.pod.topologySpreadConstraints }}
        - maxSkew: {{ $tsc.maxSkew | default 1 }}
          topologyKey: {{ $tsc.topologyKey | default "topology.kubernetes.io/zone" }}
          whenUnsatisfiable: {{ $tsc.whenUnsatisfiable | default "DoNotSchedule" }}
          labelSelector:
            matchLabels:
            {{- if $tsc.labelSelector }}
              {{- toYaml $tsc.labelSelector | nindent 14 }}
            {{- else }}
              {{- range $key, $value := $selectorLabels }}
              {{ $key }}: {{ $value }}
              {{- end }}
            {{- end }}
        {{- if and $tsc.minDomains (semverCompare ">=1.24-0" $kubeVersion) }}
          minDomains: {{ $tsc.minDomains }}
        {{- end }}
        {{- if and $tsc.matchLabelKeys (semverCompare ">=1.25-0" $kubeVersion) }}
          matchLabelKeys: {{ $tsc.matchLabelKeys }}
        {{- end }}
        {{- if and $tsc.nodeAffinityPolicy (semverCompare ">=1.25-0" $kubeVersion) }}
          nodeAffinityPolicy: {{ $tsc.nodeAffinityPolicy }}
        {{- end }}
        {{- if and $tsc.nodeTaintsPolicy (semverCompare ">=1.25-0" $kubeVersion) }}
          nodeTaintsPolicy: {{ $tsc.nodeTaintsPolicy }}
        {{- end }}
      {{- end }}
    {{- end }}
      containers:
        - name: {{ $svcName }}
        {{- if $.Values.pod.lifecycle }}
          lifecycle:
            {{- toYaml $.Values.pod.lifecycle | nindent 12 }}
        {{- end }}
          image: "{{ $.Values.image.registry }}/{{ ($worker.image).repository | default (include "docker.imageRepo" $) }}:{{ (($worker.image).tag | default $dockerImageTag) | default $chartAppVersion }}"
          imagePullPolicy: {{ ($worker.image).pullPolicy | default $dockerImagePullPolicy }}
        {{- if ($worker.pod).command }}
          command: {{ $worker.pod.command }}
          {{- if ($worker.pod).args }}
          {{- range ($worker.pod).args }}
            - {{ . | quote }}
          {{- end }}
          args: {{ $worker.pod.args }}
          {{- end }}
        {{- end }}
          ports:
            - name: {{ $containerPortName }}
              containerPort: {{ $appPort }}
              protocol: {{ $.Values.service.port.protocol | default "TCP" }}
          {{- if ($worker.pod).ports }}
            {{- range $port := ($worker.pod).ports }}
            - name: {{ $port.name }}
              containerPort: {{ $port.targetPort }}
              protocol: {{ $port.protocol | default "TCP" }}
            {{- end }}
          {{- end }}
          {{- if and ($worker.prometheus).enabled (ne (int ($worker.prometheus).port) (int $appPort)) }}
            - name: metrics
              containerPort: {{ $worker.prometheus.port }}
              protocol: TCP
          {{- end }}
          livenessProbe:
          {{- if (($worker.pod).livenessProbe).useTCPSocket }}
            tcpSocket:
              port: {{ (($worker.pod).livenessProbe).port | default $containerPortName }}
          {{- else if (($worker.pod).livenessProbe).useEXEC }}
            exec:
              command:
              {{- if (($worker.pod).livenessProbe).customCommand }}
                {{- toYaml (($worker.pod).livenessProbe).customCommand |nindent 16 }}
              {{- else }}
                - /bin/bash
                - -c
                - {{ (($worker.pod).livenessProbe).command }}
              {{- end }}
          {{- else if and (($worker.pod).livenessProbe).useGRPC (semverCompare ">=1.23-0" $kubeVersion) }}
            grpc:
              port: {{ (($worker.pod).livenessProbe).port | default $appPort }}
          {{- else }}
            httpGet:
              path: {{ (($worker.pod).livenessProbe).path | default (include "k8s.serviceLivenessProbePath" $) }}
              port: {{ (($worker.pod).livenessProbe).port | default $containerPortName }}
          {{- end }}
            initialDelaySeconds: {{ $.Values.pod.livenessProbe.initialDelaySeconds | default 5 }}
            periodSeconds: {{ $.Values.pod.livenessProbe.periodSeconds | default 10 }}
            timeoutSeconds: {{ $.Values.pod.livenessProbe.timeoutSeconds | default 1 }}
            successThreshold: {{ $.Values.pod.livenessProbe.successThreshold | default 1 }}
            failureThreshold: {{ $.Values.pod.livenessProbe.failureThreshold | default 3 }}
          readinessProbe:
          {{- if (($worker.pod).readinessProbe).useTCPSocket }}
            tcpSocket:
              port: {{ (($worker.pod).readinessProbe).port | default $containerPortName }}
          {{- else if (($worker.pod).readinessProbe).useEXEC }}
            exec:
              command:
              {{- if (($worker.pod).readinessProbe).customCommand }}
                {{- toYaml (($worker.pod).readinessProbe).customCommand |nindent 16 }}
              {{- else }}
                - /bin/bash
                - -c
                - {{ (($worker.pod).readinessProbe).command }}
              {{- end }}
          {{- else if and (($worker.pod).readinessProbe).useGRPC (semverCompare ">=1.23-0" $kubeVersion) }}
            grpc:
              port: {{ (($worker.pod).readinessProbe).port | default $appPort }}
          {{- else }}
            httpGet:
              path: {{ (($worker.pod).readinessProbe).path | default (include "k8s.serviceReadinessProbePath" $) }}
              port: {{ (($worker.pod).readinessProbe).port | default $containerPortName }}
          {{- end }}
            initialDelaySeconds: {{ $.Values.pod.readinessProbe.initialDelaySeconds | default 5 }}
            periodSeconds: {{ $.Values.pod.readinessProbe.periodSeconds | default 10 }}
            timeoutSeconds: {{ $.Values.pod.readinessProbe.timeoutSeconds | default 1 }}
            successThreshold: {{ $.Values.pod.readinessProbe.successThreshold | default 1 }}
            failureThreshold: {{ $.Values.pod.readinessProbe.failureThreshold | default 3 }}
          env:
          {{- with ($worker.deployment).customEnvVars }}
            {{- toYaml . | nindent 12 }}
          {{- end }}
          {{- if or $primaryCluster (eq $.Values.cluster.environment "dev") }}
            - name: DD_ENV
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['tags.datadoghq.com/env']
            - name: DD_SERVICE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['tags.datadoghq.com/service']
            - name: DD_VERSION
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['tags.datadoghq.com/version']
          {{- end }}
          {{- if $otlpMetricsWorkerEnabled }}
            - name: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
              value: {{ cat "http://$(DD_AGENT_HOST):" $otlpPort "/v1/metrics" | nospace }}
            - name: OTEL_RESOURCE_ATTRIBUTES
              value: >-
                metric_protocol=otlp,
                version={{ $dockerWorkerImageTag }},
                service={{ $workerName }},
                service.version={{ $dockerWorkerImageTag }},
                service.namespace={{ $.Release.Namespace }},
                kube_namespace={{ $.Release.Namespace }}
            - name: OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
              value: "delta"
            - name: OTEL_METRIC_EXPORT_INTERVAL
              value: {{ ($worker.otlpMetrics).exportInterval | default "10000" | quote }}
          {{- end }}
            - name: PLUTO_APP_ENV
              value: {{ (include "service.appEnv" $) | quote }}
            - name: PLUTO_APP_HOSTNAME
              value: {{ (include "service.hostname" $) | quote }}
            - name: PLUTO_DOCKER_IMAGE_TAG
              value: {{ $.Values.image.tag | default $chartAppVersion | quote }}
            - name: PLUTO_KVETCH_CHART_VERSION
              value: {{ (include "k8s.chartName" $) | quote }}
            - name: PLUTO_K8S_CLUSTER
              value: {{ (include "aws.eksClusterName" $) | quote }}
            - name: PLUTO_K8S_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: PLUTO_K8S_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
          {{- if $primaryCluster }}
            - name: PLUTO_OPENTELEMETRY_ENDPOINT
              value: {{ (include "open-telemetry.endpoint" $) | quote }}
          {{- end }}
            - name: SEALIGHTS_LAB_ID
              value: {{ (include "service.hostname" $) | quote }}
            - name: {{ eq (include "service.runtime" $) "node" | ternary "SL_LOG_LEVEL" "SEALIGHTS_LOG_LEVEL" }}
              value: {{ $.Values.app.seaLights.logLevel | default "fatal" | quote }}
            - name: SEALIGHTS_DISABLE
              value: {{ $seaLightsDisabled | quote }}
            - name: SEALIGHTS_FORCE_MODE
              value: {{ $seaLightsForceMode | quote }}
            - name: VAULT_ADDR
              value: {{ (include "external-secrets.secretStoreAddress" $) | quote }}
          {{- if and (eq $secrets "envs") $.Values.externalSecrets.secret.secretVariables }}
          {{- range $item := $.Values.externalSecrets.secret.secretVariables }}
            - name: {{ $item.secretKey | replace "." "_" | replace "-" "_" | upper }}
              valueFrom:
                secretKeyRef:
                  name: {{ $secretName }}
                  key: {{ $item.secretKey }}
          {{- end }}
          {{- end }}
          {{- if $.Values.debugCharts | default false }}
            - name: CLUSTER_ENABLED
              value: {{ (include "aws.eksClusterEnabled" $) | quote }}
            - name: PRIMARY_CLUSTER
              value: {{ (include "aws.eksPrimaryClusters" $) | quote }}
            - name: ISTIO_ENABLED
              value: {{ (include "istio.enabled" $) | quote }}
            - name: AUTOSCALING_ENABLED
              value: {{ (include "k8s.autoscalingEnabled" $) | quote }}
            - name: MOCK_ENABLED
              value: {{ (include "service.mockEnabled" $) | quote }}
          {{- end }}
          {{- if or $.Values.configMap.environmentVariables (eq $secrets "reference") }}
          envFrom:
          {{- if (eq $secrets "reference") }}
            - secretRef:
                name: {{ $secretName }}
          {{- end }}
          {{- if ($worker.configMap).environmentVariables }}
            - configMapRef:
                name: {{ include "k8s.configMapName" $ }}-{{ $workerName }}
          {{- end }}
          {{- end }}
          {{- with $worker.resources }}
          resources:
            {{- toYaml . | nindent 12 }}
          {{- end }}
          {{- if or $worker.volumeMounts (($worker.deployment).configVolumeMounts).enabled $secretsVolumeMountEnabled }}
          volumeMounts:
          {{- with $worker.volumeMounts }}
            {{- toYaml . | nindent 12 }}
          {{- end }}
          {{- if (($worker.deployment).configVolumeMounts).enabled }}
            - mountPath: {{ $worker.deployment.configVolumeMounts.mountPathOverride | default (cat "/app/" $svcName "-" $workerName "/config" | nospace) }}
              name: {{ $configMapVolumeName | replace "." "-" }}-{{ $workerName }}-volume
          {{- end }}
          {{- if $secretsVolumeMountEnabled }}
            - mountPath: {{ $.Values.externalSecrets.secret.volumeMount.mountPath | default (cat ($secretName | replace "." "-") "/" | nospace) }}
              name: {{ $secretName | replace "." "-" }}-volume
              readOnly: true
          {{- end }}
          {{- end }}
      {{- if ($worker.deployment).dnsConfig }}
      dnsConfig: {{- toYaml $worker.deployment.dnsConfig | nindent 8 }}
      {{- end }}
      {{- if ($worker.deployment).dnsPolicy }}
      dnsPolicy: {{ $worker.deployment.dnsPolicy | quote }}
      {{- end }}
      {{- if or $worker.volumes (($worker.deployment).configVolumeMounts).enabled $secretsVolumeMountEnabled }}
      volumes:
      {{- with $worker.volumes }}
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- if (($worker.deployment).configVolumeMounts).enabled }}
        - name: {{ $configMapVolumeName | replace "." "-" }}-{{ $workerName }}-volume
          configMap:
            name: {{ $worker.deployment.configVolumeMounts.volumeNameOverride | default (cat $configMapVolumeName "-" $workerName | nospace) }}
            items:
              - key: {{ $worker.deployment.configVolumeMounts.volumeKeyOverride | default "config" }}
                path: {{ $worker.deployment.configVolumeMounts.volumePathOverride | default (include "k8s.configFile" $) }}
      {{- end }}
      {{- if $secretsVolumeMountEnabled }}
        - name: {{ $secretName | replace "." "-" }}-volume
          secret:
            secretName: {{ $secretName }}
          {{- with $.Values.externalSecrets.secret.volumeMount.items }}
            items:
            {{- toYaml . | nindent 14 }}
          {{- end }}
      {{- end }}
      {{- end }}
      {{- with $.Values.node.selector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      affinity:
      {{- with $.Values.node.affinity.podAffinity }}
        podAffinity:
          {{- toYaml . | nindent 10 }}
      {{- end }}
      {{- with $.Values.node.affinity.podAntiAffinity }}
        podAntiAffinity:
          {{- toYaml . | nindent 10 }}
      {{- end }}
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                - key: pluto.tv/service-dedicated-group
                  operator: {{ $nodeAffinitiyOperator | quote }}
                {{- if or (eq $nodeAffinitiyOperator "In") (eq $nodeAffinitiyOperator "NotIn") }}
                  {{- if not $.Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.values }}
                    {{- fail "error: node affinity serviceDedicatedGroup values required!" }}
                  {{- end }}
                  values:
                  {{- toYaml $.Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.values | nindent 18 }}
                {{- end }}
            {{- with $.Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.serviceDedicatedGroup.additionalMatchExpressions }}
              {{- toYaml . | nindent 16 }}
            {{- end }}
          {{- with $.Values.node.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms }}
            {{- toYaml . | nindent 14 }}
          {{- end }}
        {{- with $.Values.node.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution }}
          preferredDuringSchedulingIgnoredDuringExecution:
          {{- toYaml . | nindent 10 }}
        {{- end }}
    {{- with $.Values.node.tolerations }}
      tolerations:
      {{- toYaml . | nindent 6 }}
    {{- end }}
{{- end }}
{{- end }}
