From f866909be89d7d6ea7024584e652ec54f16f5bbf Mon Sep 17 00:00:00 2001 From: Michael Lin Date: Wed, 4 Mar 2026 11:08:22 -0800 Subject: [PATCH] feat: add tls and hosts values override for more flexibility (#828) closes PLAT-443 most community charts expose the option of `.ingress.hosts` and `.ingress.tls` for ingress configuration with more flexibility. not sure why we didn't do it in the first place. this PR added these two values override that supersede `.ingress.host` and `ingress.tlsSecret` and mutually exclusive. this way it's backward compatible, and offer power user more control over ingress without reaching to `kustomize`. ### Checklist - [x] Follow the [manual testing process](https://github.com/sourcegraph/deploy-sourcegraph-helm/blob/main/TEST.md) - [ ] Update [changelog](https://github.com/sourcegraph/deploy-sourcegraph-helm/blob/main/charts/sourcegraph/CHANGELOG.md) - [x] Update [Kubernetes update doc](https://docs.sourcegraph.com/admin/updates/kubernetes) ### Test plan added unit test (cherry picked from commit 73050a97ca1b4ef5b0df16503bde831b8442ff2b) --- charts/sourcegraph/README.md | 4 +- .../sourcegraph-frontend.Ingress.yaml | 26 +++++- .../tests/frontendIngress_hosts.yaml | 6 ++ .../tests/frontendIngress_test.yaml | 92 +++++++++++++++++++ .../tests/frontendIngress_tls.yaml | 7 ++ .../tests/frontendIngress_tlsNoSecret.yaml | 6 ++ charts/sourcegraph/values.yaml | 17 +++- 7 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 charts/sourcegraph/tests/frontendIngress_hosts.yaml create mode 100644 charts/sourcegraph/tests/frontendIngress_test.yaml create mode 100644 charts/sourcegraph/tests/frontendIngress_tls.yaml create mode 100644 charts/sourcegraph/tests/frontendIngress_tlsNoSecret.yaml diff --git a/charts/sourcegraph/README.md b/charts/sourcegraph/README.md index 986d573d..f9e0c1b7 100644 --- a/charts/sourcegraph/README.md +++ b/charts/sourcegraph/README.md @@ -102,8 +102,10 @@ In addition to the documented values, all services also support the following va | frontend.ingress.annotations."kubernetes.io/ingress.class" | string | `"nginx"` | [Deprecated annotation](https://kubernetes.io/docs/concepts/services-networking/ingress/#deprecated-annotation) for specifing the IngressClass in Kubernetes 1.17 and earlier. If you are using Kubernetes 1.18+, use `ingressClassName` instead and set an override value of `null` for this annotation. | | frontend.ingress.enabled | bool | `true` | Enable ingress for the Sourcegraph server | | frontend.ingress.host | string | `""` | External hostname for the Sourcegraph server ingress (SSL) | +| frontend.ingress.hosts | list | `[]` | List of hosts for the ingress rules. Supersedes `host` if set. Cannot be set together with `host`. Example: hosts: - host: sourcegraph.example.com | | frontend.ingress.ingressClassName | string | `nil` | IngressClassName for the Ingress (Available in Kubernetes 1.18+) If you set this field, set the annotation `frontend.ingress.annotations."kubernetes.io/ingress.class"` to `null` | -| frontend.ingress.tlsSecret | string | `""` | Secret containing SSL cert | +| frontend.ingress.tls | list | `[]` | Full TLS configuration for the ingress. Supersedes `tlsSecret` if set. Cannot be set together with `tlsSecret`. Omit `secretName` for controllers that manage certificates themselves (e.g. Tailscale). Example: tls: - hosts: - sourcegraph.example.com secretName: sourcegraph-tls # optional | +| frontend.ingress.tlsSecret | string | `""` | Secret containing TLS cert. Cannot be set together with `tls`. | | frontend.name | string | `"sourcegraph-frontend"` | Name used by resources. Does not affect service names or PVCs. | | frontend.podSecurityContext | object | `{}` | Security context for the `frontend` pod, learn more from the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) | | frontend.privileged | bool | `true` | Enable creation of Role and RoleBinding (RBAC). Uses [view](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#user-facing-roles) ClusterRole if set to false | diff --git a/charts/sourcegraph/templates/frontend/sourcegraph-frontend.Ingress.yaml b/charts/sourcegraph/templates/frontend/sourcegraph-frontend.Ingress.yaml index fc08ab22..10a9c357 100644 --- a/charts/sourcegraph/templates/frontend/sourcegraph-frontend.Ingress.yaml +++ b/charts/sourcegraph/templates/frontend/sourcegraph-frontend.Ingress.yaml @@ -1,4 +1,10 @@ {{- if .Values.frontend.ingress.enabled -}} +{{- if and .Values.frontend.ingress.hosts .Values.frontend.ingress.host -}} + {{- fail "frontend.ingress.hosts and frontend.ingress.host cannot both be set" -}} +{{- end -}} +{{- if and .Values.frontend.ingress.tls .Values.frontend.ingress.tlsSecret -}} + {{- fail "frontend.ingress.tls and frontend.ingress.tlsSecret cannot both be set" -}} +{{- end -}} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: @@ -15,13 +21,30 @@ metadata: {{- end }} name: {{ .Values.frontend.name }} spec: - {{- if and .Values.frontend.ingress.host .Values.frontend.ingress.tlsSecret }} + {{- if .Values.frontend.ingress.tls }} + tls: + {{- toYaml .Values.frontend.ingress.tls | nindent 4 }} + {{- else if and .Values.frontend.ingress.host .Values.frontend.ingress.tlsSecret }} tls: - hosts: - {{ .Values.frontend.ingress.host }} secretName: {{ .Values.frontend.ingress.tlsSecret }} {{- end }} rules: + {{- if .Values.frontend.ingress.hosts }} + {{- range .Values.frontend.ingress.hosts }} + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: sourcegraph-frontend + port: + number: 30080 + host: {{ .host }} + {{- end }} + {{- else }} - http: paths: - path: / @@ -34,6 +57,7 @@ spec: {{- if .Values.frontend.ingress.host}} host: {{ .Values.frontend.ingress.host }} {{- end }} + {{- end }} {{- if .Values.frontend.ingress.ingressClassName}} ingressClassName: {{ .Values.frontend.ingress.ingressClassName }} {{- end }} diff --git a/charts/sourcegraph/tests/frontendIngress_hosts.yaml b/charts/sourcegraph/tests/frontendIngress_hosts.yaml new file mode 100644 index 00000000..ed19eab2 --- /dev/null +++ b/charts/sourcegraph/tests/frontendIngress_hosts.yaml @@ -0,0 +1,6 @@ +frontend: + ingress: + enabled: true + hosts: + - host: sourcegraph.example.com + - host: other.example.com diff --git a/charts/sourcegraph/tests/frontendIngress_test.yaml b/charts/sourcegraph/tests/frontendIngress_test.yaml new file mode 100644 index 00000000..5458c305 --- /dev/null +++ b/charts/sourcegraph/tests/frontendIngress_test.yaml @@ -0,0 +1,92 @@ +suite: frontendIngress +templates: +- frontend/sourcegraph-frontend.Ingress.yaml +tests: +# Backward-compatible: host + tlsSecret +- it: should render tls block with secretName when both host and tlsSecret are set + set: + frontend.ingress.enabled: true + frontend.ingress.host: sourcegraph.example.com + frontend.ingress.tlsSecret: sourcegraph-tls + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: sourcegraph.example.com + - equal: + path: spec.tls[0].secretName + value: sourcegraph-tls + - equal: + path: spec.rules[0].host + value: sourcegraph.example.com + +# Backward-compatible: host only → no tls block (use tls list for TLS without a secret) +- it: should not render tls block when host is set but tlsSecret is not + set: + frontend.ingress.enabled: true + frontend.ingress.host: sourcegraph.example.com + asserts: + - notExists: + path: spec.tls + +# Backward-compatible: no tls when host is not set +- it: should not render tls block when host is not set + set: + frontend.ingress.enabled: true + asserts: + - notExists: + path: spec.tls + +# New: hosts list creates one rule per host +- it: should render rules per host when hosts list is set + values: + - frontendIngress_hosts.yaml + asserts: + - equal: + path: spec.rules[0].host + value: sourcegraph.example.com + - equal: + path: spec.rules[1].host + value: other.example.com + +# New: tls list with secretName +- it: should render tls from tls list + values: + - frontendIngress_tls.yaml + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: sourcegraph.example.com + - equal: + path: spec.tls[0].secretName + value: sourcegraph-tls + +# New: tls list without secretName (e.g. Tailscale) +- it: should render tls block without secretName when tls list omits secretName + values: + - frontendIngress_tlsNoSecret.yaml + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: sourcegraph.example.com + - notExists: + path: spec.tls[0].secretName + +# Error: hosts and host both set +- it: should fail when both hosts and host are set + values: + - frontendIngress_hosts.yaml + set: + frontend.ingress.host: sourcegraph.example.com + asserts: + - failedTemplate: + errorMessage: frontend.ingress.hosts and frontend.ingress.host cannot both be set + +# Error: tls and tlsSecret both set +- it: should fail when both tls and tlsSecret are set + values: + - frontendIngress_tls.yaml + set: + frontend.ingress.tlsSecret: sourcegraph-tls + asserts: + - failedTemplate: + errorMessage: frontend.ingress.tls and frontend.ingress.tlsSecret cannot both be set diff --git a/charts/sourcegraph/tests/frontendIngress_tls.yaml b/charts/sourcegraph/tests/frontendIngress_tls.yaml new file mode 100644 index 00000000..304f2223 --- /dev/null +++ b/charts/sourcegraph/tests/frontendIngress_tls.yaml @@ -0,0 +1,7 @@ +frontend: + ingress: + enabled: true + tls: + - hosts: + - sourcegraph.example.com + secretName: sourcegraph-tls diff --git a/charts/sourcegraph/tests/frontendIngress_tlsNoSecret.yaml b/charts/sourcegraph/tests/frontendIngress_tlsNoSecret.yaml new file mode 100644 index 00000000..83481309 --- /dev/null +++ b/charts/sourcegraph/tests/frontendIngress_tlsNoSecret.yaml @@ -0,0 +1,6 @@ +frontend: + ingress: + enabled: true + tls: + - hosts: + - sourcegraph.example.com diff --git a/charts/sourcegraph/values.yaml b/charts/sourcegraph/values.yaml index 78ed3246..84af11e0 100644 --- a/charts/sourcegraph/values.yaml +++ b/charts/sourcegraph/values.yaml @@ -322,8 +322,23 @@ frontend: # -- IngressClassName for the Ingress (Available in Kubernetes 1.18+) # If you set this field, set the annotation `frontend.ingress.annotations."kubernetes.io/ingress.class"` to `null` ingressClassName: null - # -- Secret containing SSL cert + # -- Secret containing TLS cert. Cannot be set together with `tls`. tlsSecret: "" + # -- List of hosts for the ingress rules. Supersedes `host` if set. + # Cannot be set together with `host`. + # Example: + # hosts: + # - host: sourcegraph.example.com + hosts: [] + # -- Full TLS configuration for the ingress. Supersedes `tlsSecret` if set. + # Cannot be set together with `tlsSecret`. + # Omit `secretName` for controllers that manage certificates themselves (e.g. Tailscale). + # Example: + # tls: + # - hosts: + # - sourcegraph.example.com + # secretName: sourcegraph-tls # optional + tls: [] # -- Security context for the `frontend` container, # learn more from the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) containerSecurityContext: