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
      ) | 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.istio.io/managed" "istio.io-gateway-controller"
      ) | 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"
            "service.istio.io/canonical-name" .DeploymentName
            "service.istio.io/canonical-revision" "latest"
           )
          .InfrastructureLabels
          (strdict
            "gateway.networking.k8s.io/gateway-name" .Name
            "gateway.istio.io/managed" "istio.io-gateway-controller"
          ) | nindent 8 }}
    spec:
      securityContext:
      {{- if .Values.gateways.securityContext }}
        {{- toYaml .Values.gateways.securityContext | nindent 8 }}
      {{- else }}
        sysctls:
        - name: net.ipv4.ip_unprivileged_port_start
          value: "0"
      {{- if .Values.gateways.seccompProfile }}
        seccompProfile:
      {{- toYaml .Values.gateways.seccompProfile | nindent 10 }}
      {{- end }}
      {{- end }}
      serviceAccountName: {{.ServiceAccount | quote}}
      containers:
      - name: istio-proxy
      {{- 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 }}
        {{- if .Values.global.proxy.resources }}
        resources:
          {{- toYaml .Values.global.proxy.resources | nindent 10 }}
        {{- end }}
        {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}}
        securityContext:
          capabilities:
            drop:
            - ALL
          allowPrivilegeEscalation: false
          privileged: false
          readOnlyRootFilesystem: true
          runAsUser: {{ .ProxyUID | default "1337" }}
          runAsGroup: {{ .ProxyGID | default "1337" }}
          runAsNonRoot: true
        ports:
        - containerPort: 15020
          name: metrics
          protocol: TCP
        - containerPort: 15021
          name: status-port
          protocol: TCP
        - containerPort: 15090
          protocol: TCP
          name: http-envoy-prom
        args:
        - proxy
        - router
        - --domain
        - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }}
        - --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.sts.servicePort }}
        - --stsPort={{ .Values.global.sts.servicePort }}
      {{- end }}
      {{- if .Values.global.logAsJson }}
        - --log_as_json
      {{- end }}
      {{- if .Values.global.proxy.lifecycle }}
        lifecycle:
          {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }}
      {{- end }}
        env:
        - 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 }}
        - name: ISTIO_META_POD_PORTS
          value: "[]"
        - name: ISTIO_META_APP_CONTAINERS
          value: ""
        - 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 .ClusterID }}"
        - name: ISTIO_META_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: ISTIO_META_INTERCEPTION_MODE
          value: "{{ .ProxyConfig.InterceptionMode.String }}"
        {{- with (valueOrDefault  (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }}
        - name: ISTIO_META_NETWORK
          value: {{.|quote}}
        {{- end }}
        - name: ISTIO_META_WORKLOAD_NAME
          value: {{.DeploymentName|quote}}
        - 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 }}
        {{- range $key, $value := .ProxyConfig.ProxyMetadata }}
        - name: {{ $key }}
          value: "{{ $value }}"
        {{- end }}
        {{- with (index .InfrastructureLabels "topology.istio.io/network") }}
        - name: ISTIO_META_REQUESTED_NETWORK_VIEW
          value: {{.|quote}}
        {{- 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
        volumeMounts:
        - name: workload-socket
          mountPath: /var/run/secrets/workload-spiffe-uds
        - name: credential-socket
          mountPath: /var/run/secrets/credential-uds
        {{- if eq .Values.global.caName "GkeWorkloadCertificate" }}
        - name: gke-workload-certificate
          mountPath: /var/run/secrets/workload-spiffe-credentials
          readOnly: true
        {{- else }}
        - name: workload-certs
          mountPath: /var/run/secrets/workload-spiffe-credentials
        {{- end }}
        {{- if eq .Values.global.pilotCertProvider "istiod" }}
        - mountPath: /var/run/secrets/istio
          name: istiod-ca-cert
        {{- end }}
        - mountPath: /var/lib/istio/data
          name: istio-data
        # SDS channel between istioagent and Envoy
        - mountPath: /etc/istio/proxy
          name: istio-envoy
        - mountPath: /var/run/secrets/tokens
          name: istio-token
        - name: istio-podinfo
          mountPath: /etc/istio/pod
      volumes:
      - emptyDir: {}
        name: workload-socket
      - emptyDir: {}
        name: credential-socket
      {{- if eq .Values.global.caName "GkeWorkloadCertificate" }}
      - name: gke-workload-certificate
        csi:
          driver: workloadcertificates.security.cloud.google.com
      {{- else}}
      - emptyDir: {}
        name: workload-certs
      {{- end }}
      # SDS channel between istioagent and Envoy
      - emptyDir:
          medium: Memory
        name: istio-envoy
      - name: istio-data
        emptyDir: {}
      - name: istio-podinfo
        downwardAPI:
          items:
            - path: "labels"
              fieldRef:
                fieldPath: metadata.labels
            - path: "annotations"
              fieldRef:
                fieldPath: metadata.annotations
      - name: istio-token
        projected:
          sources:
          - serviceAccountToken:
              path: istio-token
              expirationSeconds: 43200
              audience: {{ .Values.global.sds.token.aud }}
      {{- if eq .Values.global.pilotCertProvider "istiod" }}
      - name: istiod-ca-cert
      {{- if eq ((.Values.pilot).env).ENABLE_CLUSTER_TRUST_BUNDLE_API true }}
        projected:
          sources:
          - clusterTrustBundle:
              name: istio.io:istiod-ca:root-cert
              path: root-cert.pem
      {{- else }}
        configMap:
          name: istio-ca-root-cert
      {{- end }}
      {{- end }}
      {{- if .Values.global.imagePullSecrets }}
      imagePullSecrets:
        {{- range .Values.global.imagePullSecrets }}
        - name: {{ . }}
        {{- end }}
      {{- end }}
---
apiVersion: v1
kind: Service
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") | nindent 4 }}
  labels:
    {{- toJsonMap
      .InfrastructureLabels
      (strdict
        "gateway.networking.k8s.io/gateway-name" .Name
      ) | 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
          ) | 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
          ) | 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}}

