#! Copyright 2020 VMware, Inc.
#! SPDX-License-Identifier: Apache-2.0

#@ load("@ytt:data", "data")

---
apiVersion: v1
kind: Namespace
metadata:
  name: #@ data.values.namespace
  labels:
    name: #@ data.values.namespace
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: #@ data.values.app_name + "-service-account"
  namespace: #@ data.values.namespace
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: #@ data.values.app_name + "-config"
  namespace: #@ data.values.namespace
  labels:
    app: #@ data.values.app_name
data:
  #@yaml/text-templated-strings
  pinniped.yaml: |
    discovery:
      url: (@= data.values.discovery_url or "null" @)
    webhook:
      url: (@= data.values.webhook_url @)
      caBundle: (@= data.values.webhook_ca_bundle @)
    api:
      servingCertificate:
        durationSeconds: (@= str(data.values.api_serving_certificate_duration_seconds) @)
        renewBeforeSeconds: (@= str(data.values.api_serving_certificate_renew_before_seconds) @)
---
#@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
apiVersion: v1
kind: Secret
metadata:
  name: image-pull-secret
  namespace: #@ data.values.namespace
  labels:
    app: #@ data.values.app_name
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: #@ data.values.image_pull_dockerconfigjson
#@ end
---
#! TODO set resource minimums (e.g. 512MB RAM) to make sure we get scheduled onto a reasonable node?
apiVersion: apps/v1
kind: Deployment
metadata:
  name: #@ data.values.app_name
  namespace: #@ data.values.namespace
  labels:
    app: #@ data.values.app_name
spec:
  replicas: 2
  selector:
    matchLabels:
      app: #@ data.values.app_name
  template:
    metadata:
      labels:
        app: #@ data.values.app_name
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ""
    spec:
      serviceAccountName: #@ data.values.app_name + "-service-account"
      #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "":
      imagePullSecrets:
        - name: image-pull-secret
      #@ end
      containers:
        - name: pinniped
          #@ if data.values.image_digest:
          image:  #@ data.values.image_repo + "@" + data.values.image_digest
          #@ else:
          image: #@ data.values.image_repo + ":" + data.values.image_tag
          #@ end
          imagePullPolicy: IfNotPresent
          args:
            - --config=/etc/config/pinniped.yaml
            - --downward-api-path=/etc/podinfo
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config
            - name: podinfo
              mountPath: /etc/podinfo
          livenessProbe:
            httpGet:
              path: /healthz
              port: 443
              scheme: HTTPS
            initialDelaySeconds: 2
            timeoutSeconds: 15
            periodSeconds: 10
            failureThreshold: 5
          readinessProbe:
            httpGet:
              path: /healthz
              port: 443
              scheme: HTTPS
            initialDelaySeconds: 2
            timeoutSeconds: 3
            periodSeconds: 10
            failureThreshold: 3
      volumes:
        - name: config-volume
          configMap:
            name: #@ data.values.app_name + "-config"
        - name: podinfo
          downwardAPI:
            items:
              - path: "labels"
                fieldRef:
                  fieldPath: metadata.labels
              - path: "namespace"
                fieldRef:
                  fieldPath: metadata.namespace
      tolerations:
        - key: CriticalAddonsOnly
          operator: Exists
        - key: node-role.kubernetes.io/master #! Allow running on master nodes too
          effect: NoSchedule
      #! "system-cluster-critical" cannot be used outside the kube-system namespace until Kubernetes >= 1.17,
      #! so we skip setting this for now (see https://github.com/kubernetes/kubernetes/issues/60596).
      #!priorityClassName: system-cluster-critical
---
apiVersion: v1
kind: Service
metadata:
  name: pinniped-api #! the golang code assumes this specific name as part of the common name during cert generation
  namespace: #@ data.values.namespace
  labels:
    app: #@ data.values.app_name
spec:
  type: ClusterIP
  selector:
    app: #@ data.values.app_name
  ports:
    - protocol: TCP
      port: 443
      targetPort: 443
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: v1alpha1.pinniped.dev
  labels:
    app: #@ data.values.app_name
spec:
  version: v1alpha1
  group: pinniped.dev
  groupPriorityMinimum: 2500 #! TODO what is the right value? https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#apiservicespec-v1beta1-apiregistration-k8s-io
  versionPriority: 10 #! TODO what is the right value? https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#apiservicespec-v1beta1-apiregistration-k8s-io
  #! caBundle: Do not include this key here. Starts out null, will be updated/owned by the golang code.
  service:
    name: pinniped-api
    namespace: #@ data.values.namespace
    port: 443