{{- /*
Copyright Broadcom, Inc. All Rights Reserved.
SPDX-License-Identifier: APACHE-2.0
*/}}

{{- if and .Values.web.enabled (include "concourse.host" .) }}
apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }}
kind: Deployment
metadata:
  name: {{ template "concourse.web.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: web
  {{- if .Values.commonAnnotations }}
  annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
  {{- end }}
spec:
  replicas: {{ .Values.web.replicaCount }}
  {{- if .Values.web.updateStrategy }}
  strategy: {{- toYaml .Values.web.updateStrategy | nindent 4 }}
  {{- end }}
  {{- $podLabels := include "common.tplvalues.merge" ( dict "values" ( list .Values.web.podLabels .Values.commonLabels ) "context" . ) }}
  selector:
    matchLabels: {{- include "common.labels.matchLabels" ( dict "customLabels" $podLabels "context" $ ) | nindent 6 }}
      app.kubernetes.io/component: web
  template:
    metadata:
      {{- if .Values.web.podAnnotations }}
      annotations: {{- include "common.tplvalues.render" (dict "value" .Values.web.podAnnotations "context" $) | nindent 8 }}
      {{- end }}
      labels: {{- include "common.labels.standard" ( dict "customLabels" $podLabels "context" $ ) | nindent 8 }}
        app.kubernetes.io/component: web
    spec:
      {{- include "concourse.imagePullSecrets" . | nindent 6 }}
      automountServiceAccountToken: {{ .Values.web.automountServiceAccountToken }}
      {{- if .Values.web.hostAliases }}
      hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.web.hostAliases "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.web.affinity }}
      affinity: {{- include "common.tplvalues.render" ( dict "value" .Values.web.affinity "context" $) | nindent 8 }}
      {{- else }}
      affinity:
        podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.web.podAffinityPreset "component" "web" "customLabels" $podLabels "context" $) | nindent 10 }}
        podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.web.podAntiAffinityPreset "component" "web" "customLabels" $podLabels "context" $) | nindent 10 }}
        nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.web.nodeAffinityPreset.type "key" .Values.web.nodeAffinityPreset.key "values" .Values.web.nodeAffinityPreset.values) | nindent 10 }}
      {{- end }}
      {{- if .Values.web.nodeSelector }}
      nodeSelector: {{- include "common.tplvalues.render" ( dict "value" .Values.web.nodeSelector "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.web.tolerations }}
      tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.web.tolerations "context" $) | nindent 8 }}
      {{- end }}
      {{- if .Values.web.topologySpreadConstraints }}
      topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.web.topologySpreadConstraints "context" .) | nindent 8 }}
      {{- end }}
      {{- if .Values.web.priorityClassName }}
      priorityClassName: {{ .Values.web.priorityClassName }}
      {{- end }}
      {{- if .Values.web.schedulerName }}
      schedulerName: {{ .Values.web.schedulerName | quote }}
      {{- end }}
      {{- if .Values.web.terminationGracePeriodSeconds }}
      terminationGracePeriodSeconds: {{ .Values.web.terminationGracePeriodSeconds }}
      {{- end }}
      {{- if .Values.web.podSecurityContext.enabled }}
      securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.web.podSecurityContext "context" $) | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ template "concourse.web.serviceAccountName" . }}
      initContainers:
        {{- if .Values.postgresql.enabled }}
        # NOTE: The value postgresql.image is not available unless postgresql.enabled is not set. We could change this to use os-shell if
        # it had the binary wait-for-port.
        # This init container is for avoiding CrashLoopback errors in the Hub container because the PostgreSQL container is not ready
        - name: wait-for-db
          image: {{ include "common.images.image" (dict "imageRoot" .Values.postgresql.image "global" .Values.global) }}
          imagePullPolicy: {{ .Values.postgresql.image.pullPolicy  }}
          command:
            - /bin/bash
          args:
            - -ec
            - |
              #!/bin/bash

              set -o errexit
              set -o nounset
              set -o pipefail

              . /opt/bitnami/scripts/libos.sh
              . /opt/bitnami/scripts/liblog.sh
              . /opt/bitnami/scripts/libpostgresql.sh

              check_postgresql_connection() {
                  echo "SELECT 1" | postgresql_remote_execute "$POSTGRESQL_CLIENT_DATABASE_HOST" "$POSTGRESQL_CLIENT_DATABASE_PORT_NUMBER" "$POSTGRESQL_CLIENT_DATABASE_NAME" "$POSTGRESQL_CLIENT_POSTGRES_USER" "$POSTGRESQL_CLIENT_CREATE_DATABASE_PASSWORD"
              }

              info "Connecting to the PostgreSQL instance $POSTGRESQL_CLIENT_DATABASE_HOST:$POSTGRESQL_CLIENT_DATABASE_PORT_NUMBER"
              if ! retry_while "check_postgresql_connection"; then
                  error "Could not connect to the database server"
                  return 1
              else
                  info "Connected to the PostgreSQL instance"
              fi
          {{- if .Values.web.containerSecurityContext.enabled }}
          securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.web.containerSecurityContext "context" $) | nindent 12 }}
          {{- end }}
          env:
            - name: POSTGRESQL_CLIENT_DATABASE_HOST
              value: {{ include "concourse.database.host" . }}
            - name: POSTGRESQL_CLIENT_DATABASE_NAME
              value: {{ include "concourse.database.name" . }}
            - name: POSTGRESQL_CLIENT_DATABASE_PORT_NUMBER
              value: {{ include "concourse.database.port" . }}
            - name: POSTGRESQL_CLIENT_CREATE_DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: {{ include "concourse.postgresql.secretName" . }}
                  key: {{ include "concourse.database.existingsecret.key" . }}
            - name: POSTGRESQL_CLIENT_POSTGRES_USER
              value: {{ include "concourse.database.user" . }}
        {{- end }}
        - name: db-migrate
          image: {{ template "concourse.image" . }}
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          command:
            - /opt/bitnami/concourse/bin/concourse
          args:
            - migrate
            - --migrate-to-latest-version
          {{- if .Values.web.containerSecurityContext.enabled }}
          securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.web.containerSecurityContext "context" $) | nindent 12 }}
          {{- end }}
          env:
            - name: CONCOURSE_POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: {{ include "concourse.postgresql.secretName" . }}
                  key: {{ include "concourse.database.existingsecret.key" . }}
            - name: CONCOURSE_POSTGRES_DATABASE
              value: {{ include "concourse.database.name" . }}
            - name: CONCOURSE_POSTGRES_HOST
              value: {{ include "concourse.database.host" . }}
            - name: CONCOURSE_POSTGRES_PORT
              value: {{ include "concourse.database.port" . }}
            - name: CONCOURSE_POSTGRES_SSLMODE
              value: {{ include "concourse.database.sslmode" . }}
            - name: CONCOURSE_POSTGRES_USER
              value: {{ include "concourse.database.user" . }}
        {{- if .Values.web.initContainers }}
        {{- include "common.tplvalues.render" (dict "value" .Values.web.initContainers "context" $) | nindent 8 }}
        {{- end }}
      containers:
        - name: concourse
          image: {{ template "concourse.image" . }}
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          {{- if .Values.web.lifecycleHooks }}
          lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.web.lifecycleHooks "context" $) | nindent 12 }}
          {{- end }}
          {{- if .Values.web.containerSecurityContext.enabled }}
          securityContext: {{- include "common.compatibility.renderSecurityContext" (dict "secContext" .Values.web.containerSecurityContext "context" $) | nindent 12 }}
          {{- end }}
          {{- if .Values.diagnosticMode.enabled }}
          command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }}
          {{- else if .Values.web.command }}
          command: {{- include "common.tplvalues.render" (dict "value" .Values.web.command "context" $) | nindent 12 }}
          {{- else }}
          command:
            - /opt/bitnami/concourse/bin/concourse
          {{- end }}
          {{- if .Values.diagnosticMode.enabled }}
          args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }}
          {{- else if .Values.web.args }}
          args: {{- include "common.tplvalues.render" (dict "value" .Values.web.args "context" $) | nindent 12 }}
          {{- else }}
          args:
            - web
          {{- end }}
          env:
            {{- if .Values.web.tsa.logLevel }}
            - name: CONCOURSE_TSA_LOG_LEVEL
              value: {{ .Values.web.tsa.logLevel | quote }}
            {{- end }}
            {{- if .Values.web.bindIp }}
            - name: CONCOURSE_BIND_IP
              value: {{ .Values.web.bindIp | quote }}
            {{- end }}
            {{- if .Values.web.tsa.bindIp }}
            - name: CONCOURSE_TSA_BIND_IP
              value: {{ .Values.web.tsa.bindIp | quote }}
            {{- end }}
            - name: CONCOURSE_TSA_BIND_PORT
              value: {{ .Values.web.containerPorts.tsa | quote }}
            {{- if .Values.web.tsa.debugBindIp }}
            - name: CONCOURSE_TSA_DEBUG_BIND_IP
              value: {{ .Values.web.tsa.debugBindIp | quote }}
            {{- end }}
            {{- if .Values.web.containerPorts.pprof }}
            - name: CONCOURSE_TSA_DEBUG_BIND_PORT
              value: {{ .Values.web.containerPorts.pprof | quote }}
            {{- end }}
            - name: CONCOURSE_BIND_PORT
              value: {{ .Values.web.containerPorts.http | quote }}
            - name: CONCOURSE_TSA_HOST_KEY
              value: "/bitnami/concourse/concourse-keys/host_key"
            - name: CONCOURSE_TSA_AUTHORIZED_KEYS
              value: "/bitnami/concourse/concourse-keys/worker_key.pub"
            - name: CONCOURSE_SESSION_SIGNING_KEY
              value: "/bitnami/concourse/concourse-keys/session_signing_key"
            - name: CONCOURSE_WEB_PUBLIC_DIR
              value: "/opt/bitnami/concourse/web/public"
            {{- if .Values.web.logLevel }}
            - name: CONCOURSE_LOG_LEVEL
              value: {{ .Values.web.logLevel | quote }}
            {{- end }}
            {{- if .Values.web.tsa.heartbeatInterval }}
            - name: CONCOURSE_TSA_HEARTBEAT_INTERVAL
              value: {{ .Values.web.tsa.heartbeatInterval | quote }}
            {{- end }}
            - name: CONCOURSE_EXTERNAL_URL
              value: {{ include "concourse.host" . | quote }}
            {{- if .Values.web.peerAddress }}
            - name: CONCOURSE_PEER_ADDRESS
              value: {{ .Values.web.peerAddress | quote }}
            {{- else }}
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: CONCOURSE_PEER_ADDRESS
              value: "$(POD_IP)"
            {{- end }}
            {{- if .Values.web.auth.mainTeam.localUser }}
            - name: CONCOURSE_MAIN_TEAM_LOCAL_USER
              value: {{ .Values.web.auth.mainTeam.localUser | quote }}
            {{- end }}
            {{- if .Values.web.auth.mainTeam.config }}
            - name: CONCOURSE_MAIN_TEAM_CONFIG
              value: /bitnami/concourse/conf/main-team.yml
            {{- end }}
            {{- if .Values.web.configRBAC }}
            - name: CONCOURSE_CONFIG_RBAC
              value: /bitnami/concourse/conf/config-rbac.yml
            {{- end }}
            {{- if .Values.web.baseResourceTypeDefaults }}
            - name: CONCOURSE_BASE_RESOURCE_TYPE_DEFAULTS
              value: /bitnami/concourse/conf/brt-defaults.yml
            {{- end }}
            {{- if .Values.secrets.localAuth.enabled }}
            - name: CONCOURSE_ADD_LOCAL_USER
              valueFrom:
                secretKeyRef:
                  name: {{ template "concourse.web.fullname" . }}
                  key: local_users
            {{- end }}
            {{- if .Values.web.clusterName }}
            - name: CONCOURSE_CLUSTER_NAME
              value: {{ .Values.web.clusterName | quote }}
            {{- end }}
            {{- if .Values.web.extraEnvVars }}
            {{- include "common.tplvalues.render" (dict "value" .Values.web.extraEnvVars "context" $) | nindent 12 }}
            {{- end }}
            {{- if .Values.web.enablePipelineInstances }}
            - name: CONCOURSE_ENABLE_PIPELINE_INSTANCES
              value: {{ .Values.web.enablePipelineInstances | quote }}
            {{- end }}
            {{- if .Values.web.enableAcrossStep }}
            - name: CONCOURSE_ENABLE_ACROSS_STEP
              value: {{ .Values.web.enableAcrossStep | quote }}
            {{- end }}
            {{- if .Values.web.auth.cookieSecure }}
            - name: CONCOURSE_COOKIE_SECURE
              value: {{ .Values.web.auth.cookieSecure | quote }}
            {{- end }}
            {{- if .Values.web.auth.duration }}
            - name: CONCOURSE_AUTH_DURATION
              value: {{ .Values.web.auth.duration | quote }}
            {{- end }}
            {{- if .Values.web.auth.passwordConnector }}
            - name: CONCOURSE_PASSWORD_CONNECTOR
              value: {{ .Values.web.auth.passwordConnector | quote }}
            {{- end }}
            {{- if .Values.web.enableCacheStreamedVolumes }}
            - name: CONCOURSE_ENABLE_CACHE_STREAMED_VOLUMES
              value: {{ .Values.web.enableCacheStreamedVolumes | quote }}
            {{- end }}
            {{- if .Values.web.tsa.gardenRequestTimeout }}
            - name: CONCOURSE_TSA_GARDEN_REQUEST_TIMEOUT
              value: {{ .Values.web.tsa.gardenRequestTimeout | quote }}
            {{- end }}
            - name: CONCOURSE_POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: {{ include "concourse.postgresql.secretName" . }}
                  key: {{ include "concourse.database.existingsecret.key" . }}
            - name: CONCOURSE_POSTGRES_DATABASE
              value: {{ include "concourse.database.name" . }}
            - name: CONCOURSE_POSTGRES_HOST
              value: {{ include "concourse.database.host" . }}
            - name: CONCOURSE_POSTGRES_PORT
              value: {{ include "concourse.database.port" . }}
            - name: CONCOURSE_POSTGRES_SSLMODE
              value: {{ include "concourse.database.sslmode" . }}
            - name: CONCOURSE_POSTGRES_USER
              value: {{ include "concourse.database.user" . }}
            {{- if .Values.web.conjur.enabled }}
            - name: CONCOURSE_CONJUR_APPLIANCE_URL
              value: {{ .Values.web.conjur.applianceUrl | quote }}
            - name: CONCOURSE_CONJUR_ACCOUNT
              valueFrom:
                secretKeyRef:
                  name: {{ template "concourse.web.fullname" . }}
                  key: conjur_account
            {{- if .Values.secrets.conjurCACert }}
            - name: CONCOURSE_CONJUR_CERT_FILE
              value: "/bitnami/concourse/conjur-keys/ca.cert"
            {{- end }}
            - name: CONCOURSE_CONJUR_AUTHN_LOGIN
              valueFrom:
                secretKeyRef:
                  name: {{ template "concourse.web.fullname" . }}
                  key: conjur_authn_login
            - name: CONCOURSE_CONJUR_AUTHN_API_KEY
              valueFrom:
                secretKeyRef:
                  name: {{ template "concourse.web.fullname" . }}
                  key: conjur_authn_api_key
            {{- if (empty .Values.secrets.conjurAuthnApiKey) }}
            - name: CONCOURSE_CONJUR_AUTHN_TOKEN_FILE
              valueFrom:
                secretKeyRef:
                  name: {{ template "concourse.web.fullname" . }}
                  key: conjur_authn_token_file
            {{- end }}
            - name: CONCOURSE_CONJUR_PIPELINE_SECRET_TEMPLATE
              value: {{ .Values.web.conjur.pipelineSecretTemplate | quote }}
            - name: CONCOURSE_CONJUR_TEAM_SECRET_TEMPLATE
              value: {{ .Values.web.conjur.teamSecretTemplate | quote }}
            - name: CONCOURSE_CONJUR_SECRET_TEMPLATE
              value: {{ .Values.web.conjur.secretTemplate | quote }}
            {{- end }}
          envFrom:
            {{- if .Values.web.extraEnvVarsCM }}
            - configMapRef:
                name: {{ include "common.tplvalues.render" (dict "value" .Values.web.extraEnvVarsCM "context" $) }}
            {{- end }}
            {{- if .Values.web.extraEnvVarsSecret }}
            - secretRef:
                name: {{ include "common.tplvalues.render" (dict "value" .Values.web.extraEnvVarsSecret "context" $) }}
            {{- end }}
          ports:
            - name: http
              containerPort: {{ .Values.web.containerPorts.http }}
            - name: tsa
              containerPort: {{ .Values.web.containerPorts.tsa }}
            {{- if .Values.web.tls.enabled }}
            - name: https
              containerPort: {{ .Values.web.containerPorts.https }}
            {{- end }}
            {{- if .Values.web.containerPorts.pprof }}
            - name: http-debug
              containerPort: {{ .Values.web.containerPorts.pprof }}
            {{- end }}
          {{- if .Values.web.resources }}
          resources: {{- toYaml .Values.web.resources | nindent 12 }}
          {{- else if ne .Values.web.resourcesPreset "none" }}
          resources: {{- include "common.resources.preset" (dict "type" .Values.web.resourcesPreset) | nindent 12 }}
          {{- end }}
          {{- if not .Values.diagnosticMode.enabled }}
          {{- if .Values.web.customStartupProbe }}
          startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.web.customStartupProbe "context" $) | nindent 12 }}
          {{- else if .Values.web.startupProbe.enabled }}
          startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.web.startupProbe "enabled") "context" $) | nindent 12 }}
            tcpSocket:
              port: http
          {{- end }}
          {{- if .Values.web.customLivenessProbe }}
          livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.web.customLivenessProbe "context" $) | nindent 12 }}
          {{- else if .Values.web.livenessProbe.enabled }}
          livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.web.livenessProbe "enabled") "context" $) | nindent 12 }}
            tcpSocket:
              port: http
          {{- end }}
          {{- if .Values.web.customReadinessProbe }}
          readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.web.customReadinessProbe "context" $) | nindent 12 }}
          {{- else if .Values.web.readinessProbe.enabled }}
          readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.web.readinessProbe "enabled") "context" $) | nindent 12 }}
            httpGet:
              path: {{ .Values.web.baseUrl | trimSuffix "/" }}/api/v1/info
              port: http
          {{- end }}
          {{- end }}
          volumeMounts:
            - name: empty-dir
              mountPath: /tmp
              subPath: tmp-dir
            - name: concourse-keys
              mountPath: /bitnami/concourse/concourse-keys
              readOnly: true
            {{- if .Values.secrets.teamAuthorizedKeys }}
            - name: team-authorized-keys
              mountPath: /bitnami/concourse/team-authorized-keys
              readOnly: true
            {{- end }}
            {{- if .Values.web.conjur.enabled }}
            - name: conjur-keys
              mountPath: /bitnami/concourse/conjur-keys
              readOnly: true
            {{- end }}
          {{- if .Values.web.extraVolumeMounts }}
          {{- include "common.tplvalues.render" (dict "value" .Values.web.extraVolumeMounts "context" $) | nindent 12 }}
          {{- end }}
        {{- if .Values.web.sidecars }}
        {{- include "common.tplvalues.render" ( dict "value" .Values.web.sidecars "context" $) | nindent 8 }}
        {{- end }}
      volumes:
        - name: empty-dir
          emptyDir: {}
        - name: concourse-configuration
          configMap:
            name: {{ include "concourse.web.configmapName" . }}
        - name: concourse-keys
          secret:
            secretName: {{ include "concourse.web.secretName" . }}
            defaultMode: 0400
            items:
              - key: host_key
                path: host_key
              - key: session_signing_key
                path: session_signing_key
              - key: worker_key.pub
                path: worker_key.pub
        {{- if .Values.secrets.teamAuthorizedKeys }}
        - name: team-authorized-keys
          secret:
            secretName: {{ include "concourse.web.secretName" }}
            defaultMode: 0400
        {{- end }}
        {{- if .Values.web.extraVolumes }}
        {{- include "common.tplvalues.render" (dict "value" .Values.web.extraVolumes "context" $) | nindent 8 }}
        {{- end }}
        {{- if .Values.web.conjur.enabled }}
        - name: conjur-keys
          secret:
            secretName: {{ template "concourse.web.fullname" . }}
            defaultMode: 0400
            items:
            - key: conjur_account
              path: conjur_account
            - key: conjur_authn_api_key
              path: conjur_authn_api_key
            - key: conjur_authn_login
              path: conjur_authn_login
            - key: conjur_authn_token_file
              path: conjur_authn_token_file
            {{- if .Values.secrets.conjurCACert }}
              - key: conjur_ca_cert
                path: ca.cert
            {{- end }}
        {{- end }}
{{- end }}
