apiVersion: apps/v1
kind:       Deployment
metadata:
  name: gazette
  labels:
    app.kubernetes.io/name: gazette
spec:
  replicas: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: gazette
  template:
    metadata:
      labels:
        app.kubernetes.io/name: gazette
    spec:
      containers:
        - name:            gazette
          image:           gazette/broker
          imagePullPolicy: Always
          ports:
            - name:          http
              containerPort: 8080
              protocol:      TCP
          readinessProbe:
            httpGet:
              path: /debug/ready
              port: http
          command:
            # Run within a shell to allow for interpretation of values.
            - "/bin/sh"
            - "-ec"
            - |
              exec gazette serve \
                --broker.port  8080 \
                --broker.zone  $(/home/gazette/.config/zonemap/node-zone.sh $NODE_NAME)
          env:
            # Addressable, advertised hostname of this broker instance.
            - name: BROKER_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            # Unique ID of this broker instance.
            - name: BROKER_ID
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            # Etcd service endpoint to use for broker coordination.
            # By default, assume an "etcd" service running in our same namespace.
            - name:  ETCD_ADDRESS
              value: "http://etcd:2379"
            # Compose an ETCD_PREFIX by composing with the well-known instance label.
            - name: ETCD_PREFIX_APP_INSTANCE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['app.kubernetes.io/instance']
            - name:  ETCD_PREFIX
              value: "/gazette/cluster/$(ETCD_PREFIX_APP_INSTANCE)"
            # Logging configuration.
            - name:  LOG_FORMAT
              value: "json"
            - name:  LOG_LEVEL
              value: "info"
            # Node hostname, used to map to a failure zone.
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            # Ask the AWS SDK to load ~/.aws/config by default, alongside ~/.aws/credentials.
            - name:  AWS_SDK_LOAD_CONFIG
              value: "1"
            # Direct the Google SDK to the well-known location for application default
            # credentials. This ENV variable isn't required, as this is the default,
            # but is provided for completeness.
            - name:  GOOGLE_APPLICATION_CREDENTIALS
              value: /home/gazette/.config/gcloud/application_default_credentials.json

          volumeMounts:
            - name:      tmpdir
              mountPath: /tmp
            - name:      zonemap
              readOnly:  true
              mountPath: /home/gazette/.config/zonemap
            - name:      gce-credentials
              readOnly:  true
              mountPath: /home/gazette/.config/gcloud
            - name:      aws-credentials
              readOnly:  true
              mountPath: /home/gazette/.aws

      volumes:
        # tmpdir is used for all ephemeral and temporary files, such as journal spools.
        # Defaults to an emptyDir, but operators may want to supply a fast local disk
        # (and note that images run as non-root user `gazette`, so use an initContainer
        # or otherwise chmod / chown to allow for access).
        - name: tmpdir
          emptyDir: {}

        # The deployment must be able to determine the failure zone of the Node
        # of each Pod. Kubernetes makes this difficult to determine, as the
        # downward API deliberately does not expose Node labels (and specifically,
        # the "failure-domain.beta.kubernetes.io/zone" label). This chart pushes
        # this mapping concern into a "gazette-zonemap" ConfigMap, which must
        # provide a "node-zone.sh" script capable of accepting a Node name and
        # returning its failure zone. The cluster operator must generate and apply
        # a suitable ConfigMap. See also:
        #   https://github.com/kubernetes/kubernetes/issues/40610
        - name: zonemap
          configMap:
            name: gazette-zonemap
            items:
              - key:  node-zone.sh
                path: node-zone.sh
                mode: 0777

        # Mount optional Secret "gazette-gce-credentials", which should contain a
        # service account private key named "service-account.json"
        # See: https://cloud.google.com/docs/authentication/production
        - name: gce-credentials
          secret:
            secretName: gazette-gce-credentials
            optional:   true
            items:
              - key:  service-account.json
                path: application_default_credentials.json # Well-known name of default credentials.

        # Mount optional Secret "gazette-aws-credentials", which should contain
        # "config" and "credentials" files. See:
        # https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html
        - name: aws-credentials
          secret:
            secretName: gazette-aws-credentials
            optional:   true

      # Give pods plenty of time to shutdown gracefully after SIGTERM.
      terminationGracePeriodSeconds: 21600
      automountServiceAccountToken:  false
