Repository navigation
bug(tenant): host-change correctness gaps (gateway doc/code mismatch, missing empty-host guard, app host drift) #4536
Description
Describe the bug
Auditing the tenant chart for what happens when an existing tenant's host value is changed (custom to derived, custom to another custom, derived to custom) surfaced three correctness gaps. Changing host is not rejected by any webhook or immutability marker (values.schema.json has no x-kubernetes-validations / @immutable on host, and the cozystack-api update path in pkg/registry/apps/application/rest.go does not validate it), so operators can reach these in normal use. Two of the three fail silently rather than erroring.
Resource names in the tenant chart are release-derived, not host-derived, so a host change updates objects in place with no in-cluster orphans. The concerns below are about silent failure modes and a doc/behavior mismatch, not orphaned resources.
Environment
- Component:
packages/apps/tenantchart (pluspackages/extra/gateway,packages/extra/ingress, and app charts such aspackages/apps/harbor) - Version: current
main(paths and line numbers below reflect the current chart) - Provider: version-independent (chart/templating logic)
To Reproduce
These are found by inspecting the chart templates and rendering, not by a runtime crash:
- Read
packages/apps/tenant/templates/_helpers.tpl:88-94and compare with thegatewayparam description. - Render an app chart (e.g. harbor) with an empty
_namespace.hostand inspect the resulting Ingress host. - Set a per-app
hoston an app, then change the tenanthost, and observe the app Ingress domain.
Expected behaviour
- The
gatewayparameter documentation matches what the chart actually does. - An empty computed apex is handled the same way across publishing paths (either both error or both skip).
- Changing a tenant's
hosteither updates all app ingress domains or clearly flags the ones it cannot.
Actual behaviour
Finding 1: gateway parameter docs describe an auto-enable behavior that is not implemented.
The gateway param description claims the chart auto-enables a Gateway for derived-apex tenants (empty host) and leaves it off for custom-apex tenants:
packages/apps/tenant/values.yaml:17packages/apps/tenant/values.schema.json:26packages/apps/tenant/README.md:83
The actual resolver ignores host entirely and returns false whenever the gateway key is unset:
{{- define "tenant.gatewayEffective" -}}
{{- if kindIs "invalid" .Values.gateway -}}false
{{- else -}}{{- if .Values.gateway -}}true{{- else -}}false{{- end -}}{{- end -}}
{{- end -}}
Source: packages/apps/tenant/templates/_helpers.tpl:88-94. The unit tests pin this real behavior (unset means off regardless of host): packages/apps/tenant/tests/gateway_default_test.yaml:37-60. So the docs, not the code, are stale. The in-code comment at _helpers.tpl:30-48 already describes the real inherit-by-default behavior.
Impact: the generated schema and UI promise behavior the chart does not deliver. An operator who sets a custom host expecting a Gateway to appear silently gets none.
Finding 2: the ingress path has no empty-host guard, unlike the gateway path.
The gateway path hard-fails when the computed apex is empty (packages/extra/gateway/templates/tenantgateway.yaml:2-4). The app ingress path has no equivalent guard:
{{- $host := .Values._namespace.host }}
{{- $harborHost := .Values.host | default (printf "%s.%s" .Release.Name $host) }}
Source: packages/apps/harbor/templates/ingress.yaml:3-4. If _namespace.host is empty, the rendered Ingress host becomes <release>. (trailing dot, malformed) with no error. The two publishing paths disagree on how they treat the same invalid input.
Finding 3: changing tenant host does not update apps that pin their own host.
App ingress hosts default to <release>.<tenant-apex> but let an app override with its own host:
{{- $harborHost := .Values.host | default (printf "%s.%s" .Release.Name $host) }}
Apps that expose a per-app host param include: harbor, kubernetes, kubernetes-nodes, tenant, vpn. When a tenant's host changes, most app ingress domains follow it in place, but any app with an explicitly set host stays on its pinned domain and drifts out of sync with the rest of the tenant. Nothing validates or warns about this divergence.
Additional context
Suggested directions (non-binding):
- Finding 1: correct the
gatewaydescription to match the code, or implement the documented host-based auto-enable. - Finding 2: add an empty-host guard in the app ingress templates, or centrally when the tenant computes host, so an empty apex fails or skips explicitly like the gateway path.
- Finding 3: document the interaction, and consider a validation or warning when an app pins a
hostthat is not a subdomain of the tenant apex.
Checklist
- I have checked the documentation
- I have searched for similar issues
- I have included all required information
- I have provided clear steps to reproduce
- I have included relevant logs
Activity
[-]bug(tenant): host-change correctness gaps — gateway doc/code mismatch, missing empty-host guard, app host drift[/-][+]bug(tenant): host-change correctness gaps (gateway doc/code mismatch, missing empty-host guard, app host drift)[/+]fix(tenant): fail fast on an empty tenant apex and correct gateway do…