Skip to content

feat(surveyor): emit metadata.namespace on all rendered resources#1159

Open
yhrn wants to merge 2 commits into
nats-io:mainfrom
yhrn:yhrn/surveyor-namespace-metadata
Open

feat(surveyor): emit metadata.namespace on all rendered resources#1159
yhrn wants to merge 2 commits into
nats-io:mainfrom
yhrn:yhrn/surveyor-namespace-metadata

Conversation

@yhrn

@yhrn yhrn commented Apr 29, 2026

Copy link
Copy Markdown

Summary

The surveyor chart never populated metadata.namespace in its rendered output, relying on helm install -n <ns> to apply the namespace via the Kubernetes API instead. This works fine for direct-install flows but breaks any workflow that renders templates statically and applies them later (helm template -n <ns> | kubectl apply -f -, kustomize+helm, ArgoCD/Flux): the manifest carries no namespace field, so resources land in the kubectl client's current context (typically default) instead of the namespace passed to helm template.

This PR adds a surveyor.namespace helper following the same jsc.namespace pattern used by the nack chart in this repo, and emits namespace: in every template's metadata block (Service, ServiceAccount, Deployment, ConfigMap, HPA, Ingress, ServiceMonitor). It defaults to .Release.Namespace and can be overridden via .Values.namespaceOverride.

This was discovered while migrating to Pulumi's pulumi-kubernetes v4.30, which bundles kustomize/api v0.21 — that release intentionally changed the namespace transformer so the kustomization-level namespace: directive no longer post-injects metadata.namespace into helm output. Charts that don't emit the field themselves end up namespace-less.

Behaviour change matrix

Workflow Before After
helm install -n my-ns works works (no diff)
helm template -n my-ns | kubectl apply -f - silently lands in kubectl's current ns lands in my-ns
helm template -n my-ns | kubectl apply -n my-ns -f - works works (the -n flag is now redundant but harmless)
helm template | kubectl apply -n target-ns -f - works (no manifest ns, kubectl -n wins) resources land in default because manifest ns now wins

The last row is the only true breaking change. It's an antipattern (the right form is helm template -n target-ns), but worth calling out.

The surveyor chart never populated metadata.namespace in its rendered
output, relying on `helm install -n <ns>` to apply the namespace via the
Kubernetes API instead. This works for direct-install flows but breaks
any workflow that renders templates statically and applies them later
(`helm template -n <ns> | kubectl apply -f -`, kustomize+helm,
ArgoCD/Flux): the manifest carries no namespace, so resources land in
the kubectl client's current context (typically "default") instead of
the namespace passed to `helm template`.

Add a `surveyor.namespace` helper following the `jsc.namespace` pattern
used by the nack chart in this repo, and emit `namespace:` in every
template's metadata block (Service, ServiceAccount, Deployment,
ConfigMap, HPA, Ingress, ServiceMonitor). Defaults to
`.Release.Namespace`; can be overridden via `.Values.namespaceOverride`.

Behaviour change matrix (previous → new):

  helm install -n my-ns                          : works → works (same)
  helm template -n my-ns | kubectl apply -f -    : silently lands in
    kubectl's current ns → lands in my-ns
  helm template -n my-ns | kubectl apply -n my-ns -f -
    : works → works (same; -n is now redundant but harmless)
  helm template | kubectl apply -n target-ns -f -
    : works (no manifest ns, kubectl -n wins) → resources land in
    "default" because manifest ns now wins (antipattern; users should
    pass `-n` to `helm template`)
@synadia-claude-reviewer

synadia-claude-reviewer Bot commented Apr 29, 2026

Copy link
Copy Markdown

Claude finished @yhrn's task in 1m 6s —— View job


PR Review: feat(surveyor): emit metadata.namespace on all rendered resources

  • Gather context (PR diff, existing templates)
  • Review _helpers.tpl namespace helper
  • Review template metadata changes
  • Check values.yaml for namespaceOverride default
  • Validate against nack's jsc.namespace pattern
  • Post final review

Overall: the approach is correct and the implementation is sound. The surveyor.namespace helper is a faithful copy of jsc.namespace from the nack chart, and namespace: is consistently added to all 7 resource templates.

One real issue

namespaceOverride is not declared in values.yaml.

The nack chart explicitly adds namespaceOverride: "" to its values.yaml (line 71). Surveyor doesn't. This means:

  • helm show values won't surface the override option to users.
  • helm lint --strict may warn about an undeclared value if a user sets it.
  • It breaks the convention the PR itself cites as its model.

Fix: add namespaceOverride: "" to values.yaml alongside nameOverride/fullnameOverride.

Minor notes (no action required)

  • trunc 63 | trimSuffix "-" on a namespace name — copied verbatim from jsc.namespace, so it's consistent. Worth knowing it could silently truncate a long namespaceOverride to a different string than intended, but this is an edge case identical to the existing nack behavior.
  • The HPA still uses autoscaling/v2beta1 (removed in K8s 1.26) and the Ingress uses networking.k8s.io/v1beta1 (removed in K8s 1.22) — both are pre-existing issues unrelated to this PR.

The breaking-change matrix in the PR description accurately describes the behavior shift and is a nice addition.

Comment thread helm/charts/surveyor/templates/_helpers.tpl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant