Skip to content

bug(tenant): host-change correctness gaps (gateway doc/code mismatch, missing empty-host guard, app host drift) #4536

Closed

Description

@IvanHunters

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/tenant chart (plus packages/extra/gateway, packages/extra/ingress, and app charts such as packages/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:

  1. Read packages/apps/tenant/templates/_helpers.tpl:88-94 and compare with the gateway param description.
  2. Render an app chart (e.g. harbor) with an empty _namespace.host and inspect the resulting Ingress host.
  3. Set a per-app host on an app, then change the tenant host, and observe the app Ingress domain.

Expected behaviour

  • The gateway parameter 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 host either 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:17
  • packages/apps/tenant/values.schema.json:26
  • packages/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 gateway description 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 host that 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

  1. added
    kind/bugCategorizes issue or PR as related to a bug
    triage/needs-triageIndicates an issue needs triage by a maintainer
    on Sep 28, 2026
  2. changed the title [-]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)[/+] on Sep 28, 2026
  3. added a commit that references this issue on Sep 28, 2026
    b2ae6b7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/bugCategorizes issue or PR as related to a bugtriage/needs-triageIndicates an issue needs triage by a maintainer

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions