{{/* The Gateway-API alternative to cyberchef.ingress.yaml (Gitea #114). WHAT THIS RENDERS, AND WHAT IT DELIBERATELY DOES NOT Only an HTTPRoute with parentRefs. No Gateway, no gatewayClassName, no Certificate, and no implementation-specific policy object (nginx-gateway- fabric's ClientSettingsPolicy, Envoy Gateway's ClientTrafficPolicy or whatever the next one calls it). That subset is the part which looks IDENTICAL on nginx-gateway-fabric, Cilium, Envoy Gateway and Istio - and keeping to it is what lets the cluster's implementation be chosen, or changed, without touching this chart again. A policy object here would bind the chart to one implementation and to a CRD whose presence it cannot check. So the class and the certificate move from this chart to the PLATFORM: they sit on the Gateway and its listeners, which belong in cluster-config, not here. ingress.clusterIssuer is therefore meaningless in this mode - the chart renders no Certificate at all - and it is not required either, because both reads of it live inside cyberchef.ingress.yaml, behind ingress.enabled. WHY A VALUE AND NOT AUTO-DETECTION .Capabilities.APIVersions is unreliable at template time (it answers from the cluster helm happens to be pointed at, and not at all for `helm template`), while an HTTPRoute without the Gateway-API CRDs fails at INSTALL time. A chart that guesses would therefore sometimes render an object the cluster rejects and sometimes silently render nothing. So the mode is a value. */}} {{- /* Null-safe like every other block this chart dereferences (#99): an override written without children - "httpRoute:" with the keys below it deleted - is YAML null, and `.Values.httpRoute.enabled` would abort the render with a nil pointer. An empty block means "chart defaults apply", and all three defaults here are empty or false, so the whole block collapses to "no HTTPRoute". */ -}} {{- $httpRoute := .Values.httpRoute | default dict -}} {{- if and $httpRoute.enabled .Values.ingress.enabled -}} {{- fail "ingress.enabled and httpRoute.enabled are both true - set exactly one of them. The Ingress and the HTTPRoute would publish the same Service under the same hostname over two different data paths, which is already a conflict at DNS level: one name, two addresses, and which one a client reaches is luck. A migration runs over a SECOND hostname (set httpRoute.hostnames explicitly while the Ingress keeps ingress.domain), never over parallel operation of both." -}} {{- end -}} {{- if $httpRoute.enabled -}} {{- $parentRefs := $httpRoute.parentRefs | default list -}} {{- if not $parentRefs -}} {{- fail "httpRoute.enabled is true but httpRoute.parentRefs is empty - an HTTPRoute without a parent attaches to no Gateway. It is created, it is schema-valid, and it routes NOTHING, with no event and no condition that says so; the only symptom is a hostname that does not answer. Name the cluster's Gateway, e.g. httpRoute.parentRefs: [{name: public, namespace: gateway}]." -}} {{- end -}} {{- /* One source of truth for the hostname: an empty httpRoute.hostnames means [ingress.domain], so the two cannot drift apart. ingress.domain is read here even though no Ingress is rendered in this mode - the value names the public hostname of this release, which is what both modes need; it is not an Ingress switch. Setting httpRoute.hostnames explicitly is what a migration over a second hostname needs, and it then wins over ingress.domain. */ -}} {{- $hostnames := $httpRoute.hostnames | default list -}} {{- if not $hostnames -}} {{- $hostnames = list (required "A Domain/Host must be provided: set ingress.domain (used as the HTTPRoute's single hostname when httpRoute.hostnames is empty) or set httpRoute.hostnames explicitly" .Values.ingress.domain) -}} {{- end -}} apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: {{ .Release.Name }}-{{ .Chart.Name }}-httproute spec: parentRefs: {{- toYaml $parentRefs | nindent 4 }} hostnames: {{- toYaml $hostnames | nindent 4 }} rules: # The Ingress counterpart is `path: / , pathType: Prefix` on the one # backend Service - CyberChef is a static bundle served at the root and has # no second path. The port is the Service's port NUMBER and not its name: # backendRefs takes a PortNumber, so unlike the Ingress this reference # cannot be made by name and the 80 below has to track # cyberchef.service.yaml by hand. ci/run-httproute-match-test.sh is what # holds that pair - it fails when a backendRef names a Service, or a port, # the same render does not create. - matches: - path: type: PathPrefix value: / backendRefs: - name: {{ .Release.Name }}-{{ .Chart.Name }}-service port: 80 {{- end }}