apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ template "opa.fullname" . }}
  labels:
{{ include "opa.labels.standard" . | indent 4 }}
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels:
      app: {{ template "opa.fullname" . }}
  {{- with .Values.deploymentStrategy }}
  strategy:
  {{- toYaml . | nindent 4 }}
  {{- end }}
  template:
    metadata:
{{- if or .Values.generateAdmissionControllerCerts .Values.opa }}
      annotations:
{{- if .Values.generateAdmissionControllerCerts }}
        checksum/certs: {{ include (print $.Template.BasePath "/webhookconfiguration.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.opa }}
        checksum/config: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }}
{{- end }}
{{- end }}
{{- if .Values.annotations }}
{{ toYaml .Values.annotations | indent 8 }}
{{- end }}
      labels:
        app: {{ template "opa.fullname" . }}
      name: {{ template "opa.fullname" . }}
    spec:
{{- if .Values.imagePullSecrets }}
      imagePullSecrets:
      {{- range .Values.imagePullSecrets }}
        - name: {{ . }}
      {{- end }}
{{- end }}
{{- if .Values.priorityClassName }}
      priorityClassName: {{ .Values.priorityClassName }}
{{- end }}
{{- if or .Values.authz.enabled .Values.bootstrapPolicies}}
      initContainers:
        - name: initpolicy
          image: {{ .Values.mgmt.image }}:{{ .Values.mgmt.imageTag }}
          imagePullPolicy: {{ .Values.mgmt.imagePullPolicy }}
          resources:
{{ toYaml .Values.mgmt.resources | indent 12 }}
          command:
          - /bin/sh
          - -c
          - |
{{- if .Values.authz.enabled }}
            tr -dc 'A-F0-9' < /dev/urandom | dd bs=1 count=32 2>/dev/null > /bootstrap/mgmt-token
            TOKEN=`cat /bootstrap/mgmt-token`
            cat > /bootstrap/authz.rego <<EOF
            package system.authz
            default allow = false
            # Allow anonymous access to the default policy decision.
            allow { input.path = [""]; input.method = "POST" }
            allow { input.path = [""]; input.method = "GET" }
            # This is only used for health check in liveness and readiness probe
            allow { input.path = ["health"]; input.method = "GET" }
{{- if .Values.prometheus.enabled }}
            # This allows metrics to be scraped by prometheus
            allow { input.path = ["metrics"]; input.method = "GET" }
{{- end }}
            allow { input.identity == "$TOKEN" }
            EOF
{{- end }}
{{- range $policyName, $policy := .Values.bootstrapPolicies }}
            cat > /bootstrap/{{ $policyName }}.rego <<EOF
{{ $policy | indent 12 }}
            EOF
{{- end }}
          volumeMounts:
            - name: bootstrap
              mountPath: /bootstrap
{{- end }}
{{- if .Values.hostNetwork.enabled }}
      hostNetwork: true
{{- end }}
      containers:
        - name: opa
          ports:
          - name: https
            containerPort: {{ .Values.port }}
{{- if .Values.prometheus.enabled }}
          - name: http
            containerPort: {{ .Values.mgmt.port }}
{{- end }}
          image: {{ .Values.image }}:{{ .Values.imageTag }}
          imagePullPolicy: {{ .Values.imagePullPolicy }}
          resources:
{{ toYaml .Values.resources | indent 12 }}
          args:
            - "run"
            - "--server"
{{- if .Values.opa }}
            - "--config-file=/config/config.yaml"
{{- end }}
            - "--tls-cert-file=/certs/tls.crt"
            - "--tls-private-key-file=/certs/tls.key"
            - "--addr=0.0.0.0:{{ .Values.port }}"
            - "--log-level={{ .Values.logLevel }}"
            - "--log-format={{ .Values.logFormat }}"
{{- if .Values.authz.enabled }}
            - "--authentication=token"
            - "--authorization=basic"
            - "--ignore=.*"
{{- end }}
{{- if .Values.prometheus.enabled }}
            - "--addr=http://0.0.0.0:{{ .Values.mgmt.port }}"
{{- else if .Values.mgmt.enabled }}
            - "--addr=http://127.0.0.1:{{ .Values.mgmt.port }}"
{{- end }}
{{- if or .Values.authz.enabled .Values.bootstrapPolicies }}
            - "/bootstrap"
{{- end }}
{{- range .Values.extraArgs }}
            - {{ . }}
{{- end }}
          volumeMounts:
            - name: certs
              readOnly: true
              mountPath: /certs
{{- if .Values.opa }}
            - name: config
              readOnly: true
              mountPath: /config
{{- end }}
{{- if or .Values.authz.enabled .Values.bootstrapPolicies }}
            - name: bootstrap
              readOnly: true
              mountPath: /bootstrap
{{- end }}
          readinessProbe:
{{ toYaml .Values.readinessProbe | indent 12 }}
          livenessProbe:
{{ toYaml .Values.livenessProbe | indent 12 }}
{{- if .Values.mgmt.enabled }}
        - name: mgmt
          image: {{ .Values.mgmt.image }}:{{ .Values.mgmt.imageTag }}
          imagePullPolicy: {{ .Values.mgmt.imagePullPolicy }}
          resources:
{{ toYaml .Values.mgmt.resources | indent 12 }}
          args:
{{- if .Values.authz.enabled }}
            - --opa-auth-token-file=/bootstrap/mgmt-token
{{- end }}
            - --opa-url=http://127.0.0.1:{{ .Values.mgmt.port }}/v1
            - --replicate-path={{ .Values.mgmt.replicate.path }}
            - --enable-data={{ .Values.mgmt.data.enabled }}
            - --enable-policies={{ .Values.mgmt.configmapPolicies.enabled }}
{{- if .Values.mgmt.configmapPolicies.enabled }}
            - --policies={{ .Values.mgmt.configmapPolicies.namespaces | join "," }}
            - --require-policy-label={{ .Values.mgmt.configmapPolicies.requireLabel }}
{{- end }}
{{- range .Values.mgmt.replicate.namespace }}
            - --replicate={{ . }}
{{- end }}
{{- range .Values.mgmt.replicate.cluster }}
            - --replicate-cluster={{ . }}
{{- end }}
{{- range .Values.mgmt.extraArgs }}
            - {{ . }}
{{- end }}
{{- if or .Values.authz.enabled .Values.bootstrapPolicies }}
          volumeMounts:
            - name: bootstrap
              readOnly: true
              mountPath: /bootstrap
{{- end }}
{{- end }}
{{- if .Values.sar.enabled }}
        - name: sarproxy
          image: {{ .Values.sar.image }}:{{ .Values.sar.imageTag }}
          imagePullPolicy: {{ .Values.sar.imagePullPolicy }}
          resources:
{{ toYaml .Values.sar.resources | indent 12 }}
          command:
            - kubectl
            - proxy
            - --accept-paths=^/apis/authorization.k8s.io/v1/subjectaccessreviews$
{{- end }}
{{- if .Values.extraContainers }}
{{ toYaml .Values.extraContainers | indent 8}}
{{- end }}
      {{- if .Values.securityContext.enabled }}
      securityContext:
        {{- range $key, $val := .Values.securityContext }}
        {{- if ne $key "enabled" }}
        {{ $key }}: {{ toYaml $val | nindent 10 }}
        {{- end }}
        {{- end }}
      {{- end }}
      serviceAccountName: {{ template "opa.serviceAccountName" .}}
      volumes:
        - name: certs
          secret:
            secretName: {{ template "opa.fullname" . }}-cert
{{- if .Values.opa }}
        - name: config
          secret:
            secretName: {{ template "opa.fullname" . }}-config
{{- end }}
{{- if or .Values.authz.enabled .Values.bootstrapPolicies}}
        - name: bootstrap
          emptyDir: {}
{{- if .Values.extraVolumes }}
{{ toYaml .Values.extraVolumes | indent 8}}
{{- end }}
{{- end }}
      affinity:
{{ toYaml .Values.affinity | indent 8 }}
      nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
      tolerations:
{{ toYaml .Values.tolerations | indent 8 }}
