{{- if .Capabilities.APIVersions.Has "apps/v1" }}
apiVersion: apps/v1
{{- else }}
apiVersion: apps/v1beta1
{{- end }}
kind: StatefulSet
metadata:
  name: {{ template "jenkins.fullname" . }}
  namespace: {{ template "jenkins.namespace" . }}
  labels:
    {{- include "jenkins.labels" . | nindent 4 }}
    {{- range $key, $val := .Values.controller.statefulSetLabels }}
    {{ $key }}: {{ $val | quote }}
    {{- end}}
  {{- if .Values.controller.statefulSetAnnotations }}
  annotations:
{{ toYaml .Values.controller.statefulSetAnnotations | indent 4 }}
  {{- end }}
spec:
  serviceName: {{ template "jenkins.fullname" . }}
  replicas: {{ include "controller.replicas" . }}
  selector:
    matchLabels:
      "app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
      "app.kubernetes.io/instance": "{{ .Release.Name }}"
  {{- if .Values.controller.updateStrategy }}
  updateStrategy:
{{ toYaml .Values.controller.updateStrategy | indent 4 }}
  {{- end }}
  template:
    metadata:
      labels:
        {{- include "jenkins.labels" . | nindent 8 }}
        {{- range $key, $val := .Values.controller.podLabels }}
        {{ $key }}: {{ $val | quote }}
        {{- end}}
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
        {{- if .Values.controller.initScripts }}
        checksum/config-init-scripts: {{ include (print $.Template.BasePath "/config-init-scripts.yaml") . | sha256sum }}
        {{- end }}
        {{- if .Values.controller.podAnnotations }}
{{ tpl (toYaml .Values.controller.podAnnotations | indent 8) . }}
        {{- end }}
    spec:
      {{- if .Values.controller.schedulerName }}
      schedulerName: {{ .Values.controller.schedulerName }}
      {{- end }}
      {{- if .Values.controller.nodeSelector }}
      nodeSelector:
{{ toYaml .Values.controller.nodeSelector | indent 8 }}
      {{- end }}
      {{- if .Values.controller.tolerations }}
      tolerations:
{{ toYaml .Values.controller.tolerations | indent 8 }}
      {{- end }}
      {{- if .Values.controller.affinity }}
      affinity:
{{ toYaml .Values.controller.affinity | indent 8 }}
      {{- end }}
      {{- if .Values.controller.topologySpreadConstraints }}
      topologySpreadConstraints:
{{ toYaml .Values.controller.topologySpreadConstraints | indent 8 }}
      {{- end }}
      {{- if .Values.controller.dnsConfig }}
      dnsConfig:
{{ toYaml .Values.controller.dnsConfig | indent 8 }}
      {{- end }}
      {{- if quote .Values.controller.terminationGracePeriodSeconds }}
      terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
      {{- end }}
      {{- if .Values.controller.priorityClassName }}
      priorityClassName: {{ .Values.controller.priorityClassName }}
      {{- end }}
      {{- if .Values.controller.shareProcessNamespace }}
      shareProcessNamespace: true
      {{- end }}
      {{- if not .Values.controller.enableServiceLinks }}
      enableServiceLinks: false
      {{- end }}
{{- if .Values.controller.usePodSecurityContext }}
      securityContext:
  {{- if kindIs "map" .Values.controller.podSecurityContextOverride }}
    {{- tpl (toYaml .Values.controller.podSecurityContextOverride | nindent 8) . -}}
  {{- else }}
    {{/* The rest of this section should be replaced with the contents of this comment one the runAsUser, fsGroup, and securityContextCapabilities Helm chart values have been removed:
        runAsUser: 1000
        fsGroup: 1000
        fsGroupChangePolicy: OnRootMismatch
        runAsNonRoot: true
    */}}
        runAsUser: {{ default 0 .Values.controller.runAsUser }}
    {{- if and (.Values.controller.runAsUser) (.Values.controller.fsGroup) }}
      {{- if not (eq (int .Values.controller.runAsUser) 0) }}
        fsGroup: {{ .Values.controller.fsGroup }}
        fsGroupChangePolicy: {{ .Values.controller.fsGroupChangePolicy }}
        runAsNonRoot: true
      {{- end }}
      {{- if .Values.controller.securityContextCapabilities }}
        capabilities:
          {{- toYaml .Values.controller.securityContextCapabilities | nindent 10 }}
      {{- end }}
    {{- end }}
  {{- end }}
{{- end }}
      serviceAccountName: "{{ template "jenkins.serviceAccountName" . }}"
      automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
{{- if .Values.controller.hostNetworking }}
      hostNetwork: true
      dnsPolicy: ClusterFirstWithHostNet
{{- end }}
      {{- if .Values.controller.hostAliases }}
      hostAliases:
        {{- toYaml .Values.controller.hostAliases | nindent 8 }}
      {{- end }}
      initContainers:
{{- if .Values.controller.customInitContainers }}
{{ tpl (toYaml .Values.controller.customInitContainers) . | indent 8 }}
{{- end }}

{{- if .Values.controller.sidecars.configAutoReload.enabled }}
{{- include "jenkins.configReloadContainer" (list $ "config-reload-init" "init") | nindent 8 }}
{{- end}}

        - name: "init"
          image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}"
          imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}"
          {{- if .Values.controller.containerSecurityContext }}
          securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }}
          {{- end }}
          command: [ "sh", "/var/jenkins_config/apply_config.sh" ]
            {{- if .Values.controller.initContainerEnvFrom }}
          envFrom:
{{ (tpl (toYaml .Values.controller.initContainerEnvFrom) .) | indent 12 }}
            {{- end }}
            {{- if .Values.controller.initContainerEnv }}
          env:
{{ (tpl (toYaml .Values.controller.initContainerEnv) .) | indent 12 }}
            {{- end }}
          resources:
{{- if .Values.controller.initContainerResources }}
{{ toYaml .Values.controller.initContainerResources | indent 12 }}
{{- else }}
{{ toYaml .Values.controller.resources | indent 12 }}
{{- end }}
          volumeMounts:
            {{- if .Values.persistence.mounts }}
{{ toYaml .Values.persistence.mounts | indent 12 }}
            {{- end }}
            - mountPath: {{ .Values.controller.jenkinsHome }}
              name: jenkins-home
              {{- if .Values.persistence.subPath }}
              subPath: {{ .Values.persistence.subPath }}
              {{- end }}
            - mountPath: /var/jenkins_config
              name: jenkins-config
            {{- if .Values.controller.installPlugins }}
            {{- if .Values.controller.overwritePluginsFromImage }}
            - mountPath: {{ .Values.controller.jenkinsRef }}/plugins
              name: plugins
            {{- end }}
            - mountPath: /var/jenkins_plugins
              name: plugin-dir
            - mountPath: /tmp
              name: tmp-volume
            {{- end }}
            {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }}
            - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d
              name: init-scripts
            {{- end }}
            {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
            {{- $httpsJKSDirPath :=  printf "%s" .Values.controller.httpsKeyStore.path }}
            - mountPath: {{ $httpsJKSDirPath }}
              name: jenkins-https-keystore
            {{- end }}
      containers:
        - name: jenkins
          image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}"
          imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}"
          {{- if .Values.controller.containerSecurityContext }}
          securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }}
          {{- end }}
          {{- if .Values.controller.overrideArgs }}
          args: [
            {{- range $overrideArg := .Values.controller.overrideArgs }}
              "{{- tpl $overrideArg $ }}",
            {{- end }}
          ]
          {{- else if .Values.controller.httpsKeyStore.enable }}
          {{- $httpsJKSFilePath :=  printf "%s/%s" .Values.controller.httpsKeyStore.path .Values.controller.httpsKeyStore.fileName }}
          args: [ "--httpPort={{.Values.controller.httpsKeyStore.httpPort}}", "--httpsPort={{.Values.controller.targetPort}}", '--httpsKeyStore={{ $httpsJKSFilePath }}', "--httpsKeyStorePassword=$(JENKINS_HTTPS_KEYSTORE_PASSWORD)" ]
          {{- else }}
          args: [ "--httpPort={{.Values.controller.targetPort}}"]
          {{- end }}
          {{- if .Values.controller.lifecycle }}
          lifecycle:
{{ toYaml .Values.controller.lifecycle | indent 12 }}
          {{- end }}
{{- if .Values.controller.terminationMessagePath }}
          terminationMessagePath: {{ .Values.controller.terminationMessagePath }}
{{- end }}
{{- if .Values.controller.terminationMessagePolicy }}
          terminationMessagePolicy: {{ .Values.controller.terminationMessagePolicy }}
{{- end }}
            {{- if .Values.controller.containerEnvFrom }}
          envFrom:
{{ (tpl ( toYaml .Values.controller.containerEnvFrom) .) | indent 12 }}
            {{- end }}
          env:
            {{- if .Values.controller.containerEnv }}
{{ (tpl ( toYaml .Values.controller.containerEnv) .) | indent 12 }}
            {{- end }}
            {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
            - name: SECRETS
              value: /run/secrets/additional
            {{- end }}
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: JAVA_OPTS
              value: >-
                {{ if .Values.controller.sidecars.configAutoReload.enabled }} -Dcasc.reload.token=$(POD_NAME) {{ end }}{{ tpl (default "" .Values.controller.javaOpts) . }}
            - name: JENKINS_OPTS
              value: >-
                {{ if .Values.controller.jenkinsUriPrefix }}--prefix={{ .Values.controller.jenkinsUriPrefix }} {{ end }} --webroot=/var/jenkins_cache/war {{ tpl (default "" .Values.controller.jenkinsOpts) . }}
            - name: JENKINS_SLAVE_AGENT_PORT
              value: "{{ .Values.controller.agentListenerPort }}"
            {{- if .Values.controller.httpsKeyStore.enable }}
            - name: JENKINS_HTTPS_KEYSTORE_PASSWORD
            {{- if not .Values.controller.httpsKeyStore.disableSecretMount }}
              valueFrom:
                secretKeyRef:
                  name: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ else if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks  {{ end }}
                  key: "{{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretKey }}"
            {{- else }}
              value: {{ .Values.controller.httpsKeyStore.password }}
            {{- end }}
            {{- end }}

            - name: CASC_JENKINS_CONFIG
              value: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}{{- if .Values.controller.JCasC.configUrls }},{{ join "," .Values.controller.JCasC.configUrls }}{{- end }}
          ports:
            {{- if .Values.controller.httpsKeyStore.enable }}
            - containerPort: {{.Values.controller.httpsKeyStore.httpPort}}
            {{- else }}
            - containerPort: {{.Values.controller.targetPort}}
            {{- end }}
              name: http
            - containerPort: {{ .Values.controller.agentListenerPort }}
              name: agent-listener
              {{- if .Values.controller.agentListenerHostPort }}
              hostPort: {{ .Values.controller.agentListenerHostPort }}
              {{- end }}
            {{- if .Values.controller.jmxPort }}
            - containerPort: {{ .Values.controller.jmxPort }}
              name: jmx
            {{- end }}
{{- range $index, $port := .Values.controller.extraPorts }}
            - containerPort: {{ $port.port }}
              name: {{ $port.name }}
{{- end }}
{{- if and .Values.controller.healthProbes .Values.controller.probes}}
  {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }}
          startupProbe:
{{ tpl (toYaml .Values.controller.probes.startupProbe | indent 12) .}}
  {{- end }}
          livenessProbe:
{{ tpl (toYaml .Values.controller.probes.livenessProbe | indent 12) .}}
          readinessProbe:
{{ tpl (toYaml .Values.controller.probes.readinessProbe | indent 12) .}}
{{- end }}
          resources:
{{ toYaml .Values.controller.resources | indent 12 }}
          volumeMounts:
{{- if .Values.persistence.mounts }}
{{ toYaml .Values.persistence.mounts | indent 12 }}
{{- end }}
            {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
            {{- $httpsJKSDirPath :=  printf "%s" .Values.controller.httpsKeyStore.path }}
            - mountPath: {{ $httpsJKSDirPath }}
              name: jenkins-https-keystore
            {{- end }}
            - mountPath: {{ .Values.controller.jenkinsHome }}
              name: jenkins-home
              readOnly: false
              {{- if .Values.persistence.subPath }}
              subPath: {{ .Values.persistence.subPath }}
              {{- end }}
            - mountPath: /var/jenkins_config
              name: jenkins-config
              readOnly: true
            {{- if .Values.controller.installPlugins }}
            - mountPath: {{ .Values.controller.jenkinsRef }}/plugins/
              name: plugin-dir
              readOnly: false
            {{- end }}
            {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }}
            - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d
              name: init-scripts
            {{- end }}
            {{- if .Values.controller.sidecars.configAutoReload.enabled }}
            - name: sc-config-volume
              mountPath: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}
            {{- end }}
            {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
            - name: jenkins-secrets
              mountPath: /run/secrets/additional
              readOnly: true
            {{- end }}
            - name: jenkins-cache
              mountPath: /var/jenkins_cache
            - mountPath: /tmp
              name: tmp-volume

{{- if .Values.controller.sidecars.configAutoReload.enabled }}
{{- include "jenkins.configReloadContainer" (list $ "config-reload" "sidecar") | nindent 8 }}
{{- end}}


{{- if .Values.controller.sidecars.additionalSidecarContainers}}
{{ tpl (toYaml .Values.controller.sidecars.additionalSidecarContainers | indent 8) .}}
{{- end }}

      volumes:
{{- if .Values.persistence.volumes }}
{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }}
{{- end }}
      {{- if .Values.controller.sidecars.configAutoReload.logging.configuration.override }}
      - name: auto-reload-config
        configMap:
          name: {{ template "jenkins.fullname" . }}-auto-reload-config
      - name: auto-reload-config-logs
        emptyDir: {}
      {{- end }}
      {{- if .Values.controller.installPlugins }}
      {{- if .Values.controller.overwritePluginsFromImage }}
      - name: plugins
        emptyDir: {}
      {{- end }}
      {{- end }}
      {{- if and .Values.controller.initScripts .Values.controller.initConfigMap }}
      - name: init-scripts
        projected:
          sources:
          - configMap:
              name: {{ template "jenkins.fullname" . }}-init-scripts
          - configMap:
              name: {{ .Values.controller.initConfigMap }}
      {{- else if .Values.controller.initConfigMap }}
      - name: init-scripts
        configMap:
          name: {{ .Values.controller.initConfigMap }}
      {{- else if .Values.controller.initScripts }}
      - name: init-scripts
        configMap:
          name: {{ template "jenkins.fullname" . }}-init-scripts
      {{- end }}
      - name: jenkins-config
        configMap:
          name: {{ template "jenkins.fullname" . }}
      {{- if .Values.controller.installPlugins }}
      - name: plugin-dir
        emptyDir: {}
      {{- end }}
      {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
      - name: jenkins-secrets
        projected:
          sources:
          {{- if .Values.controller.additionalSecrets }}
          - secret:
              name: {{ template "jenkins.fullname" . }}-additional-secrets
          {{- end }}
          {{- if .Values.controller.additionalExistingSecrets }}
          {{- range $key, $value := .Values.controller.additionalExistingSecrets }}
          - secret:
              name: {{ tpl $value.name $ }}
              items:
                - key: {{ tpl $value.keyName $ }}
                  path: {{ tpl $value.name $ }}-{{ tpl $value.keyName $ }}
          {{- end }}
          {{- end }}
          {{- if .Values.controller.admin.createSecret }}
          - secret:
              name: {{ .Values.controller.admin.existingSecret | default (include "jenkins.fullname" .) }}
              items:
                - key: {{ .Values.controller.admin.userKey | default "jenkins-admin-user" }}
                  path: chart-admin-username
                - key: {{ .Values.controller.admin.passwordKey | default "jenkins-admin-password" }}
                  path: chart-admin-password
        {{- end }}
        {{- if .Values.controller.existingSecret }}
          - secret:
              name: {{ .Values.controller.existingSecret }}
        {{- end }}
      {{- end }}
      - name: jenkins-cache
        emptyDir: {}
      {{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }}
      - name: jenkins-home
      {{- if .Values.persistence.enabled }}
        persistentVolumeClaim:
          claimName: {{ .Values.persistence.existingClaim | default (include "jenkins.fullname" .) }}
      {{- else }}
        emptyDir: {}
      {{- end -}}
      {{- end }}
      - name: sc-config-volume
        emptyDir: {}
      - name: tmp-volume
        emptyDir: {}

      {{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
      - name: jenkins-https-keystore
        secret:
          secretName: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks  {{ end }}
          items:
          - key: {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretKey }}
            path: {{ .Values.controller.httpsKeyStore.fileName }}
      {{- end }}

{{- if .Values.controller.imagePullSecretName }}
      imagePullSecrets:
      - name: {{ .Values.controller.imagePullSecretName }}
{{- end -}}
