Feature Request: Support multiple domains in istio hosts
Feature Request
Why
It would be nice if I could support multiple hosts in the istio: hosts
declaration. This would be most easily accomplished by doing the following I think...
packages:
podinfo:
enabled: true
git:
repo: https://github.com/stefanprodan/podinfo.git
tag: 6.3.4
path: charts/podinfo
wrapper:
enabled: true
sso:
enabled: true
istio:
injection: "enabled"
peerAuthentications:
- name: "podinfo"
spec:
selector:
matchLabels:
app: "podinfo"
mtls:
mode: STRICT
portLevelMtls:
9898:
mode: STRICT
hosts:
- names:
- podinfo
domains:
- test.local
- bigbang.local
gateways:
- public
destination:
port: 9898
Ideally we would also have backwards compatibility for domain:
Proposed Solution
I have the following solution which I tested and appears working
# chart/templates/istio/virtualservice.yaml
{{- /* Sets up virtual service for istio ingress */ -}}
{{- if and (dig "istio" "hosts" false .Values.package) .Values.bigbang.istio.enabled -}}
{{- range $host := .Values.package.istio.hosts -}}
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: {{ include "resourceName" (printf "%s-%s" (index $host.names 0) (default $.Values.bigbang.domain $host.domain)) }}
labels:
{{- include "commonLabels" $ | nindent 4 }}
spec:
gateways:
{{- range $host.gateways }}
- {{ ternary . (printf "istio-system/%s" .) (contains "/" .) }}
{{- end }}
hosts:
{{- range $hostNames := $host.names }}
{{- range $hostDomains := (default (list $host.domain) ($host.domains | default dict)) }}
- {{ printf "%s.%s" $hostNames (default $.Values.bigbang.domain $hostDomains) | quote }}
{{- end -}}
{{- end -}}
{{- /* Sets up default or simple route */ -}}
{{- if or $host.destination (not (or (dig "route" "http" false $host) (dig "route" "tcp" false $host) (dig "route" "tls" false $host))) -}}
{{- $dest := dict "host" (default $.Values.package.name (dig "destination" "service" nil $host)) -}}
{{- if dig "destination" "port" false $host -}}
{{- $dest = merge (dict "port" (dict "number" $host.destination.port)) $dest -}}
{{- end -}}
{{- $host = merge (dict "route" (dict "http" (append (dig "route" "http" list $host) (dict "route" (list (dict "destination" $dest)))))) $host -}}
{{- end -}}
{{- toYaml $host.route | nindent 2 }}
exportTo:
- istio-system
---
{{ end -}}
{{- end -}}
Here, we loop over host.names
like normal, but then also loop over host.domains
inside. If host.domains
exists then we loop over that, if not, we turn host.domain
into a single item list and loop over there.
The end result is the following virtual service
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
annotations:
meta.helm.sh/release-name: podinfo-wrapper
meta.helm.sh/release-namespace: podinfo
creationTimestamp: "2023-10-28T03:18:34Z"
generation: 3
labels:
app.kubernetes.io/instance: podinfo-wrapper
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: podinfo
app.kubernetes.io/version: 0.4.1_33292cc4fec1
helm.sh/chart: wrapper-0.4.1_33292cc4fec1
helm.toolkit.fluxcd.io/name: podinfo-wrapper
helm.toolkit.fluxcd.io/namespace: podinfo
name: podinfo-test-local
namespace: podinfo
resourceVersion: "25343955"
uid: fd8d1724-43c6-4442-ac5e-801f68d3672f
spec:
exportTo:
- istio-system
gateways:
- istio-system/public
hosts:
- podinfo.test.local
- podinfo.bigbang.local
http:
- route:
- destination:
host: podinfo
port:
number: 9898
Another route would be to create two virtualservices, however that would cause conflicts with things like the Gateway NetworkPolicy which I honestly didn't feel like untangling. If that is the better solution I would be more than happy to look into that though.