---
apiVersion: v1
kind: ConfigMap
metadata:
  name: credentials-sync-eventhub
data:
  # Patch this ConfigMap with additional values needed for your cloud
  KUBE_SECRET: webhook-url # does not yet exist -- will be created in the same Namespace
  ADDRESS: "fluxv2" # the Azure Event Hub name
  SYNC_PERIOD: "3600" # tokens expire; refresh faster than that

---
# This Deployment frequently fetches registry tokens and applies them as an imagePullSecret.
# It's done as a 1-replica Deployment rather than a CronJob, because CronJob scheduling can
# block cluster bootstraps and cold-reboots from obtaining registry tokens for a considerable time.
# This deployment will immediately fetch a token, which reduces latency for working image updates.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: credentials-sync-eventhub
  namespace: flux-system
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    spec:
      serviceAccountName: credentials-sync-eventhub
      securityContext:
        runAsNonRoot: true
        runAsUser: 1001
      containers:
        - image: busybox # override this with a cloud-specific image
          name: sync
          envFrom:
            - configMapRef:
                name: credentials-sync-eventhub
          env:
            - name: RECONCILE_SH # override this env var with a shell function in a kustomize patch
              value: |-
                reconcile() {
                  echo reconciling...
                }
          command:
            - bash
            - -ceu
            - |-
              # template reconcile() into the script
              # env var is expanded by k8s before the pod starts
              $(RECONCILE_SH)

              apply-secret() {
                /kbin/kubectl create secret generic "$1" \
                  --from-literal=token="$2" \
                  --from-literal=address="$3" \
                  --dry-run=client -o=yaml \
                  | grep -v "creationTimestamp:" \
                  | /kbin/kubectl apply -f -
              }

              pause_loop() {
                sleep "$SYNC_PERIOD" || true
              }

              graceful_exit() {
                echo "Trapped signal -- $(date)"
                job_ids="$(
                  jobs \
                    | grep "pause_loop" \
                    | cut -d] -f1 \
                    | tr [ %
                  )"
                # shellcheck disable=SC2086
                if [ "$job_ids" ]; then
                  kill $job_ids
                fi
                wait
                echo "Graceful exit -- $(date)"
              }

              trap graceful_exit INT TERM

              echo "Loop started (period: $SYNC_PERIOD s) -- $(date)"
              while true; do
                reconcile & wait $!
                pause_loop & wait $!
              done
          resources: {}
          volumeMounts:
            - mountPath: /.azure
              name: cache-volume
      volumes:
        - emptyDir: {}
          name: cache-volume

# RBAC necessary for our Deployment to apply our secret that will store the JWT token
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: credentials-sync-eventhub
  namespace: flux-system
rules:
  - apiGroups: [""]
    resources:
      - secrets
    verbs:
      - get
      - create
      - update
      - patch
    # Lock this down to the specific Secret name  (Optional)
    #resourceNames:
    # - $(KUBE_SECRET) # templated from kustomize vars referencing ConfigMap, also see kustomizeconfig.yaml
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: credentials-sync-eventhub
  namespace: flux-system
subjects:
  - kind: ServiceAccount
    name: credentials-sync-eventhub
roleRef:
  kind: Role
  name: credentials-sync-eventhub
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: credentials-sync-eventhub
  namespace: flux-system