{{- if .Values.ingressGateways.enabled }} {{- if not .Values.connectInject.enabled }}{{ fail "connectInject.enabled must be true" }}{{ end -}} {{- if and .Values.global.adminPartitions.enabled (not .Values.global.enableConsulNamespaces) }}{{ fail "global.enableConsulNamespaces must be true if global.adminPartitions.enabled=true" }}{{ end }} {{- if .Values.global.lifecycleSidecarContainer }}{{ fail "global.lifecycleSidecarContainer has been renamed to global.consulSidecarContainer. Please set values using global.consulSidecarContainer." }}{{ end }} {{ template "consul.validateRequiredCloudSecretsExist" . }} {{ template "consul.validateCloudSecretKeys" . }} {{- $root := . }} {{- $defaults := .Values.ingressGateways.defaults }} {{- $names := dict }} {{- /* Check if gateway names are unique. */ -}} {{- $gateways := .Values.ingressGateways.gateways }} {{- range $outerIngressIndex, $outerIngressVal := $gateways }} {{- range $innerIngressIndex, $innerIngressVal := $gateways }} {{- if (and (ne $outerIngressIndex $innerIngressIndex) (eq $outerIngressVal.name $innerIngressVal.name)) }} {{ fail (cat "ingress gateways must have unique names but found duplicate name" $innerIngressVal.name) }} {{ end -}} {{ end -}} {{ end -}} {{- range .Values.ingressGateways.gateways }} {{- $service := .service }} {{- if empty .name }} # Check that the gateway name is provided {{ fail "Ingress gateway names cannot be empty"}} {{ end -}} {{- if hasKey $names .name }} # Check that the gateway name is unique {{ fail "Ingress gateway names must be unique"}} {{ end -}} {{- /* Add the gateway name to the $names dict to ensure uniqueness */ -}} {{- $_ := set $names .name .name }} apiVersion: apps/v1 kind: Deployment metadata: name: {{ template "consul.fullname" $root }}-{{ .name }} namespace: {{ $root.Release.Namespace }} labels: app: {{ template "consul.name" $root }} chart: {{ template "consul.chart" $root }} heritage: {{ $root.Release.Service }} release: {{ $root.Release.Name }} component: ingress-gateway ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} spec: replicas: {{ default $defaults.replicas .replicas }} selector: matchLabels: app: {{ template "consul.name" $root }} chart: {{ template "consul.chart" $root }} heritage: {{ $root.Release.Service }} release: {{ $root.Release.Name }} component: ingress-gateway ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} template: metadata: labels: app: {{ template "consul.name" $root }} chart: {{ template "consul.chart" $root }} heritage: {{ $root.Release.Service }} release: {{ $root.Release.Name }} component: ingress-gateway ingress-gateway-name: {{ template "consul.fullname" $root }}-{{ .name }} consul.hashicorp.com/connect-inject-managed-by: consul-k8s-endpoints-controller annotations: "consul.hashicorp.com/connect-inject": "false" "consul.hashicorp.com/gateway-kind": "ingress-gateway" "consul.hashicorp.com/gateway-consul-service-name": "{{ .name }}" {{- if $root.Values.global.enableConsulNamespaces }} "consul.hashicorp.com/gateway-namespace": {{ (default $defaults.consulNamespace .consulNamespace) }} {{- end }} "consul.hashicorp.com/gateway-wan-address-source": "Service" {{- $serviceType := (default $defaults.service.type $service.type) }} {{- if (eq $serviceType "NodePort") }} {{- if $service.ports }} {{- $firstPort := first $service.ports}} {{- if $firstPort.nodePort }} "consul.hashicorp.com/gateway-wan-port": "{{ $firstPort.nodePort }}" {{- else }}{{ fail "if ingressGateways .service.type=NodePort and defining ingressGateways.gateways.service.ports, the first port entry must include a nodePort" }} {{- end }} {{- else if $defaults.service.ports }} {{- $firstDefaultPort := first $defaults.service.ports}} {{- if $firstDefaultPort.nodePort }} "consul.hashicorp.com/gateway-wan-port": "{{ $firstDefaultPort.nodePort }}" {{- else }}{{ fail "if ingressGateways .service.type=NodePort and using ingressGateways.defaults.service.ports, the first port entry must include a nodePort" }} {{- end }} {{- else }}{{ fail "if ingressGateways .service.type=NodePort, the first port entry in either the defaults or specific gateway must include a nodePort" }} {{- end }} {{- else }} {{- if $service.ports }} {{- $firstPort := first $service.ports}} {{- if $firstPort.port }} "consul.hashicorp.com/gateway-wan-port": "{{ $firstPort.port }}" {{- else }}{{ fail "if ingressGateways .service.type is not NodePort and defining ingressGateways.gateways.service.ports, the first port entry must include a port" }} {{- end }} {{- else if $defaults.service.ports }} {{- $firstDefaultPort := first $defaults.service.ports}} {{- if $firstDefaultPort.port }} "consul.hashicorp.com/gateway-wan-port": "{{ $firstDefaultPort.port }}" {{- else }}{{ fail "if ingressGateways .service.type is not NodePort and using ingressGateways.defaults.service.ports, the first port entry must include a port" }} {{- end }} {{- else }}{{ fail "if ingressGateways .service.type is not NodePort, the first port entry in either the defaults or specific gateway must include a port" }} {{- end }} {{- end }} {{- if (and $root.Values.global.secretsBackend.vault.enabled $root.Values.global.tls.enabled) }} "vault.hashicorp.com/agent-init-first": "true" "vault.hashicorp.com/agent-inject": "true" "vault.hashicorp.com/role": {{ $root.Values.global.secretsBackend.vault.consulCARole }} "vault.hashicorp.com/agent-inject-secret-serverca.crt": {{ $root.Values.global.tls.caCert.secretName }} "vault.hashicorp.com/agent-inject-template-serverca.crt": {{ template "consul.serverTLSCATemplate" $root }} {{- if and $root.Values.global.secretsBackend.vault.ca.secretName $root.Values.global.secretsBackend.vault.ca.secretKey }} "vault.hashicorp.com/agent-extra-secret": {{ $root.Values.global.secretsBackend.vault.ca.secretName }} "vault.hashicorp.com/ca-cert": /vault/custom/{{ $root.Values.global.secretsBackend.vault.ca.secretKey }} {{- end }} {{- if $root.Values.global.secretsBackend.vault.agentAnnotations }} {{ tpl $root.Values.global.secretsBackend.vault.agentAnnotations $root | nindent 8 | trim }} {{- end }} {{- end }} {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} "prometheus.io/scrape": "true" "prometheus.io/path": "/metrics" "prometheus.io/port": "20200" {{- end }} {{- if $defaults.annotations }} # We allow both default annotations and gateway-specific annotations {{- tpl $defaults.annotations $root | nindent 8 }} {{- end }} {{- if .annotations }} {{- tpl .annotations $root | nindent 8 }} {{- end }} spec: {{- if (or $defaults.affinity .affinity) }} affinity: {{ tpl (default $defaults.affinity .affinity) $root | nindent 8 | trim }} {{- end }} {{- if (or $defaults.tolerations .tolerations) }} tolerations: {{ tpl (default $defaults.tolerations .tolerations) $root | nindent 8 | trim }} {{- end }} {{- if (or $defaults.topologySpreadConstraints .topologySpreadConstraints) }} topologySpreadConstraints: {{ tpl (default $defaults.topologySpreadConstraints .topologySpreadConstraints) $root | nindent 8 | trim }} {{- end }} terminationGracePeriodSeconds: {{ default $defaults.terminationGracePeriodSeconds .terminationGracePeriodSeconds }} serviceAccountName: {{ template "consul.fullname" $root }}-{{ .name }} volumes: - name: consul-service emptyDir: medium: "Memory" {{- if $root.Values.global.tls.enabled }} {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} - name: consul-ca-cert secret: {{- if $root.Values.global.tls.caCert.secretName }} secretName: {{ $root.Values.global.tls.caCert.secretName }} {{- else }} secretName: {{ template "consul.fullname" $root }}-ca-cert {{- end }} items: - key: {{ default "tls.crt" $root.Values.global.tls.caCert.secretKey }} path: tls.crt {{- end }} {{- end }} initContainers: # ingress-gateway-init registers the ingress gateway service with Consul. - name: ingress-gateway-init image: {{ $root.Values.global.imageK8S }} env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName {{- include "consul.consulK8sConsulServerEnvVars" $root | nindent 8 }} {{- if $root.Values.global.enableConsulNamespaces }} - name: CONSUL_NAMESPACE value: {{ (default $defaults.consulNamespace .consulNamespace) }} {{- end }} {{- if $root.Values.global.acls.manageSystemACLs }} - name: CONSUL_LOGIN_AUTH_METHOD value: {{ template "consul.fullname" $root }}-k8s-component-auth-method - name: CONSUL_LOGIN_DATACENTER value: {{ $root.Values.global.datacenter }} - name: CONSUL_LOGIN_META value: "component=ingress-gateway,pod=$(NAMESPACE)/$(POD_NAME)" {{- end }} - name: CONSUL_NODE_NAME value: $(NODE_NAME)-virtual command: - "/bin/sh" - "-ec" - | consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${NAMESPACE} \ -gateway-kind="ingress-gateway" \ -proxy-id-file=/consul/service/proxy-id \ -service-name={{ template "consul.fullname" $root }}-{{ .name }} \ -log-level={{ default $root.Values.global.logLevel }} \ -log-json={{ $root.Values.global.logJSON }} volumeMounts: - name: consul-service mountPath: /consul/service {{- if $root.Values.global.tls.enabled }} {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true {{- end }} {{- end }} resources: requests: memory: "50Mi" cpu: "50m" limits: memory: "50Mi" cpu: "50m" containers: - name: ingress-gateway image: {{ $root.Values.global.imageConsulDataplane | quote }} {{- if (default $defaults.resources .resources) }} resources: {{ toYaml (default $defaults.resources .resources) | nindent 10 }} {{- end }} volumeMounts: - name: consul-service mountPath: /consul/service readOnly: true {{- if $root.Values.global.tls.enabled }} {{- if not (or (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots) ($root.Values.global.secretsBackend.vault.enabled)) }} - name: consul-ca-cert mountPath: /consul/tls/ca readOnly: true {{- end }} {{- end }} env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: DP_ENVOY_READY_BIND_ADDRESS valueFrom: fieldRef: fieldPath: status.podIP - name: DP_CREDENTIAL_LOGIN_META1 value: pod=$(NAMESPACE)/$(POD_NAME) - name: DP_CREDENTIAL_LOGIN_META2 value: component=ingress-gateway - name: DP_SERVICE_NODE_NAME value: $(NODE_NAME)-virtual command: - consul-dataplane args: - -envoy-ready-bind-port=21000 {{- if $root.Values.externalServers.enabled }} - -addresses={{ $root.Values.externalServers.hosts | first }} {{- else }} - -addresses={{ template "consul.fullname" $root }}-server.{{ $root.Release.Namespace }}.svc {{- end }} {{- if $root.Values.externalServers.enabled }} - -grpc-port={{ $root.Values.externalServers.grpcPort }} {{- else }} - -grpc-port=8502 {{- end }} - -proxy-service-id-path=/consul/service/proxy-id {{- if $root.Values.global.enableConsulNamespaces }} - -service-namespace={{ (default $defaults.consulNamespace .consulNamespace) }} {{- end }} {{- if and $root.Values.global.tls.enabled }} {{- if (not (and $root.Values.externalServers.enabled $root.Values.externalServers.useSystemRoots)) }} {{- if $root.Values.global.secretsBackend.vault.enabled }} - -ca-certs=/vault/secrets/serverca.crt {{- else }} - -ca-certs=/consul/tls/ca/tls.crt {{- end }} {{- end }} {{- if and $root.Values.externalServers.enabled $root.Values.externalServers.tlsServerName }} - -tls-server-name={{ $root.Values.externalServers.tlsServerName }} {{- else if $root.Values.global.cloud.enabled }} - -tls-server-name=server.{{ $root.Values.global.datacenter}}.{{ $root.Values.global.domain}} {{- end }} {{- else }} - -tls-disabled {{- end }} {{- if $root.Values.global.acls.manageSystemACLs }} - -credential-type=login - -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token - -login-auth-method={{ template "consul.fullname" $root }}-k8s-component-auth-method {{- if $root.Values.global.adminPartitions.enabled }} - -login-partition={{ $root.Values.global.adminPartitions.name }} {{- end }} {{- end }} {{- if $root.Values.global.adminPartitions.enabled }} - -service-partition={{ $root.Values.global.adminPartitions.name }} {{- end }} - -log-level={{ default $root.Values.global.logLevel }} - -log-json={{ $root.Values.global.logJSON }} {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} - -telemetry-prom-scrape-path=/metrics {{- end }} {{- if and $root.Values.externalServers.enabled $root.Values.externalServers.skipServerWatch }} - -server-watch-disabled=true {{- end }} livenessProbe: tcpSocket: port: 21000 failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 readinessProbe: tcpSocket: port: 21000 failureThreshold: 3 initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 5 ports: - name: gateway-health containerPort: 21000 {{- range $index, $allPorts := (default $defaults.service.ports $service.ports) }} - name: gateway-{{ $index }} containerPort: {{ $allPorts.port }} {{- end }} {{- if (default $defaults.priorityClassName .priorityClassName) }} priorityClassName: {{ default $defaults.priorityClassName .priorityClassName | quote }} {{- end }} {{- if (default $defaults.nodeSelector .nodeSelector) }} nodeSelector: {{ tpl (default $defaults.nodeSelector .nodeSelector) $root | indent 8 | trim }} {{- end }} --- {{- end }} {{- end }}