apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{.ServiceAccount | quote}}
  namespace: {{.Namespace | quote}}
  annotations:
    {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }}
  labels:
    {{- toJsonMap
      .InfrastructureLabels
      (strdict
        "gateway.networking.k8s.io/gateway-name" .Name
        "gateway.networking.k8s.io/gateway-class-name" .GatewayClass
      ) | nindent 4 }}
  {{- if ge .KubeVersion 128 }}
  # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412
  ownerReferences:
  - apiVersion: gateway.networking.k8s.io/v1beta1
    kind: Gateway
    name: "{{.Name}}"
    uid: "{{.UID}}"
  {{- end }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{.DeploymentName | quote}}
  namespace: {{.Namespace | quote}}
  annotations:
    {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }}
  labels:
    {{- toJsonMap
      .InfrastructureLabels
      (strdict
        "gateway.networking.k8s.io/gateway-name" .Name
        "gateway.networking.k8s.io/gateway-class-name" .GatewayClass
        "gateway.istio.io/managed" .ControllerLabel
      ) | nindent 4 }}
  ownerReferences:
  - apiVersion: gateway.networking.k8s.io/v1beta1
    kind: Gateway
    name: "{{.Name}}"
    uid: "{{.UID}}"
spec:
  selector:
    matchLabels:
      "{{.GatewayNameLabel}}": "{{.Name}}"
  template:
    metadata:
      annotations:
        {{- toJsonMap
          (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version")
          (strdict "istio.io/rev" (.Revision | default "default"))
          (strdict
            "prometheus.io/path" "/stats/prometheus"
            "prometheus.io/port" "15020"
            "prometheus.io/scrape" "true"
          ) | nindent 8 }}
      labels:
        {{- toJsonMap
          (strdict
            "sidecar.istio.io/inject" "false"
            "istio.io/dataplane-mode" "none"
            "service.istio.io/canonical-name" .DeploymentName
            "service.istio.io/canonical-revision" "latest"
           )
          .InfrastructureLabels
          (strdict
            "gateway.networking.k8s.io/gateway-name" .Name
            "gateway.networking.k8s.io/gateway-class-name" .GatewayClass
            "gateway.istio.io/managed" .ControllerLabel
          ) | nindent 8}}
    spec:
      {{- if .Values.global.waypoint.affinity }}
      affinity:
      {{- toYaml .Values.global.waypoint.affinity | nindent 8 }}
      {{- end }}
      {{- if .Values.global.waypoint.topologySpreadConstraints }}
      topologySpreadConstraints:
      {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }}
      {{- end }}
      {{- if .Values.global.waypoint.nodeSelector }}
      nodeSelector:
      {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }}
      {{- end }}
      {{- if .Values.global.waypoint.tolerations }}
      tolerations:
      {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }}
      {{- end }}
      serviceAccountName: {{.ServiceAccount | quote}}
      containers:
      - name: istio-proxy
        ports:
        - containerPort: 15020
          name: metrics
          protocol: TCP
        - containerPort: 15021
          name: status-port
          protocol: TCP
        - containerPort: 15090
          protocol: TCP
          name: http-envoy-prom
        {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }}
        image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}"
        {{- else }}
        image: "{{ .ProxyImage }}"
        {{- end }}
        {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}}
        args:
        - proxy
        - waypoint
        - --domain
        - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }}
        - --serviceCluster
        - {{.ServiceAccount}}.$(POD_NAMESPACE)
        - --proxyLogLevel
        - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}}
        - --proxyComponentLogLevel
        - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}}
        - --log_output_level
        - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}}
        {{- if .Values.global.logAsJson }}
        - --log_as_json
        {{- end }}
        {{- if .Values.global.proxy.outlierLogPath }}
        - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }}
        {{- end}}
        env:
        - name: ISTIO_META_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
        - name: ISTIO_META_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: PILOT_CERT_PROVIDER
          value: {{ .Values.global.pilotCertProvider }}
        - name: CA_ADDR
        {{- if .Values.global.caAddress }}
          value: {{ .Values.global.caAddress }}
        {{- else }}
          value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012
        {{- end }}
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: INSTANCE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
        - name: HOST_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: ISTIO_CPU_LIMIT
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        - name: PROXY_CONFIG
          value: |
                 {{ protoToJSON .ProxyConfig }}
        {{- if .ProxyConfig.ProxyMetadata }}
        {{- range $key, $value := .ProxyConfig.ProxyMetadata }}
        - name: {{ $key }}
          value: "{{ $value }}"
        {{- end }}
        {{- end }}
        - name: GOMEMLIMIT
          valueFrom:
            resourceFieldRef:
              resource: limits.memory
        - name: GOMAXPROCS
          valueFrom:
            resourceFieldRef:
              resource: limits.cpu
        - name: ISTIO_META_CLUSTER_ID
          value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}"
        {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }}
        {{- if $network }}
        - name: ISTIO_META_NETWORK
          value: "{{ $network }}"
        {{- end }}
        - name: ISTIO_META_INTERCEPTION_MODE
          value: REDIRECT
        - name: ISTIO_META_WORKLOAD_NAME
          value: {{.DeploymentName}}
        - name: ISTIO_META_OWNER
          value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}
        {{- if .Values.global.meshID }}
        - name: ISTIO_META_MESH_ID
          value: "{{ .Values.global.meshID }}"
        {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}
        - name: ISTIO_META_MESH_ID
          value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}"
        {{- end }}
        {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}
        - name: TRUST_DOMAIN
          value: "{{ . }}"
        {{- end }}
        {{- if .Values.global.waypoint.resources }}
        resources:
        {{- toYaml .Values.global.waypoint.resources | nindent 10 }}
        {{- end }}
        startupProbe:
          failureThreshold: 30
          httpGet:
            path: /healthz/ready
            port: 15021
            scheme: HTTP
          initialDelaySeconds: 1
          periodSeconds: 1
          successThreshold: 1
          timeoutSeconds: 1
        readinessProbe:
          failureThreshold: 4
          httpGet:
            path: /healthz/ready
            port: 15021
            scheme: HTTP
          initialDelaySeconds: 0
          periodSeconds: 15
          successThreshold: 1
          timeoutSeconds: 1
        securityContext:
          privileged: false
        {{- if not (eq .Values.global.platform "openshift") }}
          runAsGroup: 1337
          runAsUser: 1337
        {{- end }}
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          capabilities:
            drop:
            - ALL
{{- if .Values.gateways.seccompProfile }}
          seccompProfile:
{{- toYaml .Values.gateways.seccompProfile | nindent 12 }}
{{- end }}
        volumeMounts:
        - mountPath: /var/run/secrets/workload-spiffe-uds
          name: workload-socket
        - mountPath: /var/run/secrets/istio
          name: istiod-ca-cert
        - mountPath: /var/lib/istio/data
          name: istio-data
        - mountPath: /etc/istio/proxy
          name: istio-envoy
        - mountPath: /var/run/secrets/tokens
          name: istio-token
        - mountPath: /etc/istio/pod
          name: istio-podinfo
      volumes:
      - emptyDir: {}
        name: workload-socket
      - emptyDir:
          medium: Memory
        name: istio-envoy
      - emptyDir:
          medium: Memory
        name: go-proxy-envoy
      - emptyDir: {}
        name: istio-data
      - emptyDir: {}
        name: go-proxy-data
      - downwardAPI:
          items:
          - fieldRef:
              fieldPath: metadata.labels
            path: labels
          - fieldRef:
              fieldPath: metadata.annotations
            path: annotations
        name: istio-podinfo
      - name: istio-token
        projected:
          sources:
          - serviceAccountToken:
              audience: istio-ca
              expirationSeconds: 43200
              path: istio-token
      - name: istiod-ca-cert
      {{- if eq (.Values.pilot.env).ENABLE_CLUSTER_TRUST_BUNDLE_API true }}
        projected:
          sources:
          - clusterTrustBundle:
              name: istio.io:istiod-ca:{{ .Values.global.trustBundleName | default "root-cert" }}
              path: root-cert.pem
      {{- else }}
        configMap:
          name: {{ .Values.global.trustBundleName | default "istio-ca-root-cert" }}
      {{- end }}
      {{- if .Values.global.imagePullSecrets }}
      imagePullSecrets:
        {{- range .Values.global.imagePullSecrets }}
        - name: {{ . }}
        {{- end }}
      {{- end }}
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    {{ toJsonMap
      (strdict "networking.istio.io/traffic-distribution" "PreferClose")
      (omit .InfrastructureAnnotations
        "kubectl.kubernetes.io/last-applied-configuration"
        "gateway.istio.io/name-override"
        "gateway.istio.io/service-account"
        "gateway.istio.io/controller-version"
      ) | nindent 4 }}
  labels:
    {{- toJsonMap
      .InfrastructureLabels
      (strdict
        "gateway.networking.k8s.io/gateway-name" .Name
        "gateway.networking.k8s.io/gateway-class-name" .GatewayClass
      ) | nindent 4 }}
  name: {{.DeploymentName | quote}}
  namespace: {{.Namespace | quote}}
  ownerReferences:
  - apiVersion: gateway.networking.k8s.io/v1beta1
    kind: Gateway
    name: "{{.Name}}"
    uid: "{{.UID}}"
spec:
  ipFamilyPolicy: PreferDualStack
  ports:
  {{- range $key, $val := .Ports }}
  - name: {{ $val.Name | quote }}
    port: {{ $val.Port }}
    protocol: TCP
    appProtocol: {{ $val.AppProtocol }}
  {{- end }}
  selector:
    "{{.GatewayNameLabel}}": "{{.Name}}"
  {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }}
  loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}}
  {{- end }}
  type: {{ .ServiceType | quote }}
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: {{.DeploymentName | quote}}
  namespace: {{.Namespace | quote}}
  annotations:
    {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }}
  labels:
    {{- toJsonMap
          .InfrastructureLabels
          (strdict
          "gateway.networking.k8s.io/gateway-name" .Name
          "gateway.networking.k8s.io/gateway-class-name" .GatewayClass
          ) | nindent 4 }}
  ownerReferences:
    - apiVersion: gateway.networking.k8s.io/v1beta1
      kind: Gateway
      name: {{.Name}}
      uid: "{{.UID}}"
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name:  {{.DeploymentName | quote}}
  maxReplicas: 1
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: {{.DeploymentName | quote}}
  namespace: {{.Namespace | quote}}
  annotations:
    {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }}
  labels:
    {{- toJsonMap
          .InfrastructureLabels
          (strdict
          "gateway.networking.k8s.io/gateway-name" .Name
          "gateway.networking.k8s.io/gateway-class-name" .GatewayClass
          ) | nindent 4 }}
  ownerReferences:
    - apiVersion: gateway.networking.k8s.io/v1beta1
      kind: Gateway
      name: {{.Name}}
      uid: "{{.UID}}"
spec:
  selector:
    matchLabels:
      gateway.networking.k8s.io/gateway-name: {{.Name|quote}}

