{{- $subsets := .Subsets }}
{{- $cluster := .Cluster }}
{{- range $i, $subset := $subsets }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ $.Service }}-{{ $subset.Version }}
spec:
  replicas: 1
  selector:
    matchLabels:
      istio.io/test-vm: {{ $.Service }}
      istio.io/test-vm-version: {{ $subset.Version }}
  template:
    metadata:
      annotations:
        # Sidecar is inside the pod to simulate VMs - do not inject
        sidecar.istio.io/inject: "false"
      labels:
        # Label should not be selected. We will create a workload entry instead
        istio.io/test-vm: {{ $.Service }}
        istio.io/test-vm-version: {{ $subset.Version }}
    spec:
      # Disable kube-dns, to mirror VM
      # we set policy to none and explicitly provide a set of invalid values
      # for nameservers, search namespaces, etc. ndots is set to 1 so that
      # the application will first try to resolve the hostname (a, a.ns, etc.) as is
      # before attempting to add the search namespaces.
      dnsPolicy: None
      dnsConfig:
        nameservers:
        - "8.8.8.8"
        searches:
        - "com"
        options:
        - name: "ndots"
          value: "1"
{{- if $.VM.IstioHost }}
      # Override the istiod host to force traffic through east-west gateway.
      hostAliases:
      - ip: {{ $.VM.IstioIP }}
        hostnames:
        - {{ $.VM.IstioHost }}
{{- end }}
      # Disable service account mount, to mirror VM
      automountServiceAccountToken: false
      {{- if $.ImagePullSecretName }}
      imagePullSecrets:
      - name: {{ $.ImagePullSecretName }}
      {{- end }}
      containers:
      - name: istio-proxy
        image: {{ $.ImageHub }}/{{ $.VM.Image }}:{{ $.ImageTag }}
        imagePullPolicy: {{ $.ImagePullPolicy }}
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
          runAsUser: 1338
          runAsGroup: 1338
        command:
        - bash
        - -c
        - |-
          # To support image builders which cannot do RUN, do the run commands at startup.
          # This exploits the fact the images remove the installer once its installed.
          # This is a horrible idea for production images, but these are just for tests.
          [[ -f /tmp/istio-sidecar-centos-7.rpm ]] && sudo rpm -vi /tmp/istio-sidecar-centos-7.rpm && sudo rm /tmp/istio-sidecar-centos-7.rpm
          [[ -f /tmp/istio-sidecar.rpm ]] && sudo rpm -vi /tmp/istio-sidecar.rpm && sudo rm /tmp/istio-sidecar.rpm
          [[ -f /tmp/istio-sidecar.deb ]] && sudo dpkg -i /tmp/istio-sidecar.deb && sudo rm /tmp/istio-sidecar.deb

          # Read root cert from and place signed certs here (can't mount directly or the dir would be unwritable)
          sudo mkdir -p /var/run/secrets/istio

          # hack: remove certs that are bundled in the image
          sudo rm /var/run/secrets/istio/cert-chain.pem
          sudo rm /var/run/secrets/istio/key.pem
          sudo chown -R istio-proxy /var/run/secrets

          # place mounted bootstrap files (token is mounted directly to the correct location)
          sudo cp /var/run/secrets/istio/bootstrap/root-cert.pem /var/run/secrets/istio/root-cert.pem
          sudo cp /var/run/secrets/istio/bootstrap/*.env /var/lib/istio/envoy/
          sudo cp /var/run/secrets/istio/bootstrap/mesh.yaml /etc/istio/config/mesh

          # don't overwrite /etc/hosts since it's managed by kubeproxy
          #sudo sh -c 'cat /var/run/secrets/istio/bootstrap/hosts >> /etc/hosts'

          # since we're not overwriting /etc/hosts on k8s, verify that istiod hostname in /etc/hosts
          # matches the value generated by istioctl
          echo "checking istio host"
          SYSTEM_HOST=$(cat /etc/hosts | grep istiod)
          ISTIOCTL_HOST=$(cat /var/run/secrets/istio/bootstrap/hosts | grep istiod)
          if [ "$(echo "$SYSTEM_HOST" | tr -d '[:space:]')" != "$(echo "$ISTIOCTL_HOST" | tr -d '[:space:]')" ]; then
            echo "istiod host in /etc/hosts does not match value generated by istioctl"
            echo "/etc/hosts: $SYSTEM_HOST"
            echo "/var/run/secrets/istio/bootstrap/hosts: $ISTIOCTL_HOST"
            exit 1
          fi
          echo "istiod host ok"

          # read certs from correct directory
          sudo sh -c 'echo PROV_CERT=/var/run/secrets/istio >> /var/lib/istio/envoy/cluster.env'
          sudo sh -c 'echo OUTPUT_CERTS=/var/run/secrets/istio >> /var/lib/istio/envoy/cluster.env'

          # su will mess with the limits set on the process we run. This may lead to quickly exhausting the file limits
          # We will get the host limit and set it in the child as well.
          # TODO(https://superuser.com/questions/1645513/why-does-executing-a-command-in-su-change-limits) can we do better?
          currentLimit=$(ulimit -n)

          # Run the pilot agent and Envoy
          # TODO: run with systemctl?
          export ISTIO_AGENT_FLAGS="--concurrency 2 --proxyLogLevel warning,misc:error,rbac:debug,jwt:debug"
          sudo -E -s /bin/bash -c "ulimit -n ${currentLimit}; exec /usr/local/bin/istio-start.sh&"

          /usr/local/bin/server --cluster "{{ $cluster }}" --version "{{ $subset.Version }}" \
{{- range $i, $p := $.ContainerPorts }}
{{- if eq .Protocol "GRPC" }}
             --grpc \
{{- else if eq .Protocol "TCP" }}
             --tcp \
{{- else }}
             --port \
{{- end }}
             "{{ $p.Port }}" \
{{- if $p.ServerFirst }}
             --server-first={{ $p.Port }} \
{{- end }}
{{- if $p.TLS }}
             --tls={{ $p.Port }} \
{{- end }}
{{- if $p.InstanceIP }}
             --bind-ip={{ $p.Port }} \
{{- end }}
{{- if $p.LocalhostIP }}
             --bind-localhost={{ $p.Port }} \
{{- end }}
{{- end }}
             --crt=/var/lib/istio/cert.crt \
             --key=/var/lib/istio/cert.key
        env:
        - name: INSTANCE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        volumeMounts:
        - mountPath: /var/run/secrets/tokens
          name: {{ $.Service }}-istio-token
        - mountPath: /var/run/secrets/istio/bootstrap
          name: istio-vm-bootstrap
        {{- range $name, $value := $subset.Annotations }}
        {{- if eq $name.Name "sidecar.istio.io/bootstrapOverride" }}
        - mountPath: /etc/istio-custom-bootstrap
          name: custom-bootstrap-volume
        {{- end }}
        {{- end }}
{{- if $.IncludeExtAuthz }}
      - name: ext-authz
        image: {{ $.ImageHub }}/ext-authz:{{ $.ImageTag }}
        imagePullPolicy: {{ $.ImagePullPolicy }}
        ports:
        - containerPort: 8000
        - containerPort: 9000
{{- end }}
      volumes:
      - secret:
          secretName: {{ $.Service }}-istio-token
        name: {{ $.Service }}-istio-token
      - configMap:
          name: {{ $.Service }}-{{ $subset.Version }}-vm-bootstrap
        name: istio-vm-bootstrap
      {{- range $name, $value := $subset.Annotations }}
      {{- if eq $name.Name "sidecar.istio.io/bootstrapOverride" }}
      - name: custom-bootstrap-volume
        configMap:
          name: {{ $value.Value }}
      {{- end }}
      {{- end }}
{{- end}}
