apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}
  namespace: {{ .Release.Namespace }}
  labels:
    app.kubernetes.io/name: {{ .Release.Name }}
    app.kubernetes.io/component: kube-apiserver
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ .Release.Name }}
      app.kubernetes.io/component: kube-apiserver
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ .Release.Name }}
        app.kubernetes.io/component: kube-apiserver
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                topologyKey: kubernetes.io/hostname
                labelSelector:
                  matchExpressions:
                    - key: app.kubernetes.io/name
                      operator: In
                      values:
                        - {{ .Release.Name }}
                    - key: app.kubernetes.io/component
                      operator: In
                      values:
                        - kube-apiserver
      tolerations:
        - effect: NoExecute
          operator: Exists
      initContainers:
        - name: init
          image: {{ printf "%s/%s:%s" .Values.images.init.registry .Values.images.init.repository .Values.images.init.tag }}
          imagePullPolicy: {{ .Values.images.init.pullPolicy }}
          command:
            - /bin/sh
            - -c
            - |
{{ .Files.Get "scripts/_gen_controller_manager_kubeconfig.sh" | indent 14 }}
              TOKEN_AUTH_FILE=/srv/kubernetes/token/probe
              cat >> $TOKEN_AUTH_FILE << EOF
              {{ .Values.probe.token }},{{ .Values.probe.user }},{{ .Values.probe.uid }},system:unauthenticated
              EOF
          volumeMounts:
            - name: kube-controller-manager-secret
              mountPath: /tmp/kube-controller-manager-secret
            - name: kube-controller-manager-kubeconfig
              mountPath: srv/kubernetes/controller-manager
            - name: kube-apiserver-token
              mountPath: /srv/kubernetes/token
      containers:
        - name: kube-apiserver
          image: {{ printf "%s/kube-apiserver:%s" .Values.images.apiServer.registry .Values.images.apiServer.tag }}
          imagePullPolicy: {{ .Values.images.apiServer.pullPolicy }}
          command:
            - kube-apiserver
            - --tls-cert-file=/srv/kubernetes/apiserver/tls.crt
            - --tls-private-key-file=/srv/kubernetes/apiserver/tls.key
            - --etcd-cafile=/srv/kubernetes/etcd/ca/ca.crt
            - --etcd-certfile=/srv/kubernetes/etcd/client/tls.crt
            - --etcd-keyfile=/srv/kubernetes/etcd/client/tls.key
            - --etcd-servers={{ .Values.etcd.endpoints }}
            - --enable-admission-plugins=Priority,NamespaceLifecycle,LimitRanger,PodSecurityPolicy,ServiceAccount,NodeRestriction,DefaultStorageClass,DefaultTolerationSeconds,ResourceQuota,StorageObjectInUseProtection,MutatingAdmissionWebhook,ValidatingAdmissionWebhook
            - --allow-privileged=true
            - --anonymous-auth=false
            - --authorization-mode=Node,RBAC
            - --client-ca-file=/srv/kubernetes/ca/tls.crt
            - --enable-bootstrap-token-auth=true
            - --token-auth-file=/srv/kubernetes/token/probe
            - --kubelet-preferred-address-types=InternalIP,Hostname,ExternalIP
            {{ if .Values.apiServer.oidcIssuerURL }}
            - --oidc-issuer-url={{ .Values.apiServer.oidcIssuerURL }}
            - --oidc-client-id={{ .Values.apiServer.oidcClientID }}
            - --oidc-username-claim=email
            - --oidc-groups-claim=groups
            {{- if .Values.apiServer.oidcCaSecretName }}
            - --oidc-ca-file=/srv/kubernetes/identity-ca/ca.crt
            {{- end }}
            {{ end }}
            - --requestheader-client-ca-file=/srv/kubernetes/aggregator-ca/tls.crt
            - --proxy-client-cert-file=/srv/kubernetes/aggregator/tls.crt
            - --proxy-client-key-file=/srv/kubernetes/aggregator/tls.key
            - --requestheader-extra-headers-prefix=X-Remote-Extra-
            - --requestheader-group-headers=X-Remote-Group
            - --requestheader-username-headers=X-Remote-User
            - --secure-port=443
            - --service-cluster-ip-range=100.64.0.0/13
            - --service-account-issuer=https://{{ .Release.Name }}.{{ .Release.Name }}.svc.{{ .Values.clusterDomain }}
            - --service-account-key-file=/srv/kubernetes/service-account-key/tls.key
            - --service-account-signing-key-file=/srv/kubernetes/service-account-key/tls.key
            - --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
            - --v=2
          livenessProbe:
            httpGet:
              scheme: HTTPS
              path: /livez
              port: 443
              httpHeaders:
                - name: Authorization
                  value: Bearer {{ .Values.probe.token }}
            successThreshold: 1
            failureThreshold: 3
            initialDelaySeconds: 15
            periodSeconds: 30
            timeoutSeconds: 15
          readinessProbe:
            httpGet:
              scheme: HTTPS
              path: /readyz
              port: 443
              httpHeaders:
                - name: Authorization
                  value: Bearer {{ .Values.probe.token }}
            successThreshold: 1
            failureThreshold: 3
            initialDelaySeconds: 10
            periodSeconds: 30
            timeoutSeconds: 15
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          ports:
            - name: https
              containerPort: 443
              protocol: TCP
          resources:
{{ toYaml .Values.resources.kubeApiserver | indent 12 }}
          volumeMounts:
            - name: ca-kube-apiserver
              mountPath: /srv/kubernetes/ca
            - name: kube-apiserver
              mountPath: /srv/kubernetes/apiserver
            - name: service-account-key
              mountPath: /srv/kubernetes/service-account-key
            - name: ca-etcd
              mountPath: /srv/kubernetes/etcd/ca
            - name: etcd-client-tls
              mountPath: /srv/kubernetes/etcd/client
            - name: kube-apiserver-token
              mountPath: /srv/kubernetes/token
            - name: ca-front-proxy
              mountPath: /srv/kubernetes/aggregator-ca
            - name: kube-aggregator
              mountPath: /srv/kubernetes/aggregator
            {{- if .Values.apiServer.oidcCaSecretName }}
            - name: ca-identity
              mountPath: /srv/kubernetes/identity-ca
            {{- end }}
        - name: kube-controller-manager
          image: {{ printf "%s/kube-controller-manager:%s" .Values.images.apiServer.registry .Values.images.apiServer.tag }}
          imagePullPolicy: {{ .Values.images.apiServer.pullPolicy }}
          command:
            - kube-controller-manager
            - --cluster-signing-cert-file=/srv/kubernetes/ca/tls.crt
            - --cluster-signing-key-file=/srv/kubernetes/ca/tls.key
            - --controllers=namespace,serviceaccount,serviceaccount-token,clusterrole-aggregation,garbagecollector,csrapproving,csrcleaner,csrsigning,bootstrapsigner,tokencleaner
            - --authorization-kubeconfig=/srv/kubernetes/controller-manager/kubeconfig
            - --authentication-kubeconfig=/srv/kubernetes/controller-manager/kubeconfig
            - --kubeconfig=/srv/kubernetes/controller-manager/kubeconfig
            - --root-ca-file=/srv/kubernetes/ca/tls.crt
            - --service-account-private-key-file=/srv/kubernetes/service-account-key/tls.key
            - --use-service-account-credentials=true
            - --v=2
          livenessProbe:
            failureThreshold: 2
            httpGet:
              path: /healthz
              port: 10252
              scheme: HTTP
            initialDelaySeconds: 15
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 15
          resources:
{{ toYaml .Values.resources.kubeControllerManager | indent 12 }}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - name: ca-kube-apiserver
              mountPath: /srv/kubernetes/ca
            - name: service-account-key
              mountPath: /srv/kubernetes/service-account-key
            - name: kube-controller-manager-kubeconfig
              mountPath: srv/kubernetes/controller-manager
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      terminationGracePeriodSeconds: 30
      volumes:
        - name: ca-kube-apiserver
          secret:
            secretName: {{ .Release.Name }}-ca
        - name: kube-apiserver
          secret:
            secretName: {{ .Release.Name }}
        - name: service-account-key
          secret:
            secretName: {{ .Release.Name }}-service-account-key
        - name: kube-controller-manager-kubeconfig
          emptyDir: {}
        - name: kube-controller-manager-secret
          secret:
            secretName: {{ .Release.Name }}-kube-controller-manager
        - name: kube-apiserver-token
          emptyDir: {}
        - name: ca-front-proxy
          secret:
            secretName: {{ .Release.Name }}-aggregator-ca
        - name: kube-aggregator
          secret:
            secretName: {{ .Release.Name }}-aggregator
        - name: ca-etcd
          secret:
            secretName: {{ .Values.etcd.secretNames.ca | default "etcd-ca" }}
        - name: etcd-client-tls
          secret:
            secretName: {{ .Values.etcd.secretNames.client | default "etcd-client" }}
        {{- if .Values.apiServer.oidcCaSecretName }}
        - name: ca-identity
          secret:
            secretName: {{ .Values.apiServer.oidcCaSecretName }}
        {{- end }}
