Skip to content

fix(nebariapp): render auth and landingPage blocks via toYaml passthrough#94

Open
viniciusdc wants to merge 1 commit into
mainfrom
fix/nebariapp-auth-landingpage-passthrough
Open

fix(nebariapp): render auth and landingPage blocks via toYaml passthrough#94
viniciusdc wants to merge 1 commit into
mainfrom
fix/nebariapp-auth-landingpage-passthrough

Conversation

@viniciusdc

@viniciusdc viniciusdc commented May 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #57.

templates/nebariapp.yaml hand-rendered the auth and landingPage blocks field-by-field, covering only a subset of what the NebariApp CRD defines. Every CRD field the chart doesn't list explicitly is silently dropped — which is why deployments needing enforceAtGateway, groups, tokenExchange, etc. have been resorting to post-hoc kubectl patch.

Switch both blocks to toYaml | nindent 4 passthrough, matching the neighboring routing block (which has done this since nebari-operator#114 added routing.tls.secretName and the field was usable immediately, no chart change needed).

What changes

   {{- with .Values.nebariapp.auth }}
   auth:
-    enabled: {{ .enabled | default true }}
-    provider: {{ .provider | default "keycloak" }}
-    provisionClient: {{ .provisionClient | default true }}
-    redirectURI: {{ .redirectURI | default "/oauth2/callback" }}
-    {{- with .scopes }}
-    scopes:
-      {{- toYaml . | nindent 6 }}
-    {{- end }}
-    {{- if hasKey . "enforceAtGateway" }}
-    enforceAtGateway: {{ .enforceAtGateway }}
-    {{- end }}
-    ...
+    {{- toYaml . | nindent 4 }}
   {{- end }}

Same transform for landingPage. Net diff: -50 / +2.

The JupyterHub-specific defaults that the template was carrying (enabled: true, redirectURI: /hub/oauth_callback, enforceAtGateway: false, forwardAccessToken: false, the standard scope set, the full landingPage block including the healthCheck sub-object) all live in values.yaml already, so users who don't override anything get the exact same rendered output. The template-level | default clauses were only relevant in the edge case where a user explicitly removed those fields from their overrides — which would have been a user-driven choice anyway.

Verification

helm template . --set nebariapp.hostname=test.local before vs after produces the same NebariApp resource, field-for-field. Only the field ordering inside spec.auth and spec.landingPage differs because toYaml emits keys alphabetically instead of in the order the hand-rendered template declared them — purely cosmetic. The deployed CRD doesn't care about field order.

Rendered output of the new template (relevant excerpt):

spec:
  hostname: test.local
  service:
    name: proxy-public
    port: 80
  auth:
    enabled: true
    enforceAtGateway: false
    forwardAccessToken: false
    provider: keycloak
    provisionClient: true
    redirectURI: /hub/oauth_callback
    scopes:
    - openid
    - profile
    - email
    - groups
  landingPage:
    category: Data Science
    description: Interactive Python notebooks for data science
    displayName: JupyterHub
    enabled: false
    healthCheck:
      enabled: true
      intervalSeconds: 30
      path: /hub/api/health
      timeoutSeconds: 5
    icon: https://jupyter.org/assets/homepage/main-logo.svg
    priority: 1

Follow-up

This is the local fix. The broader question — that every NebariApp-using pack in the org (8–10 charts and counting) re-implements its own copy of templates/nebariapp.yaml and drifts independently from the CRD — is being tracked separately as a library-chart proposal in nebari-dev/nebari-operator. The passthrough shape adopted here is intentionally a one-line {{ include "nebari.app.spec" . }} swap away from consuming such a library chart whenever one ships.

Test plan

  • helm template renders the same NebariApp resource as before (verified locally)
  • CI passes on this branch
  • After merge: a follow-up smoke test sets a previously-unconfigurable field (e.g., nebariapp.auth.enforceAtGateway: true, or nebariapp.auth.groups) and confirms it lands in the deployed NebariApp spec

…ough

templates/nebariapp.yaml hand-rendered the auth block field-by-field,
covering only 5 of the 14 fields the NebariApp.spec.auth CRD defines.
The other 9 (enforceAtGateway, clientSecretRef, denyRedirect,
deviceFlowClient, groups, issuerURL, keycloakConfig, spaClient,
tokenExchange) were silently dropped if a user tried to set them via
values, forcing post-hoc kubectl patches to communicate fields the
chart didn't expose.

The landingPage block had the same shape: every sub-field hand-rendered,
so any CRD addition would be silently dropped until the template caught
up.

Switch both blocks to `toYaml | nindent 4` passthrough, matching what
the neighboring `routing` block already does. Every CRD field is now
addressable from values.yaml. The JupyterHub-specific defaults
(enabled: true, redirectURI: /hub/oauth_callback, enforceAtGateway:
false, forwardAccessToken: false, the standard scopes set, landingPage
defaults, healthCheck config) all live in values.yaml already, so the
default chain is unchanged for users who don't override.

Verified with `helm template`: rendered NebariApp.spec matches the
previous output field-for-field; only field ordering differs because
toYaml emits sorted keys.

Fixes #57.
@viniciusdc

Copy link
Copy Markdown
Contributor Author

@oren-openteams would you like to test this? and see if it helps bypass the need for the in-place patches?

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.

Render full nebariapp.auth block via toYaml so all CRD fields are configurable from values

2 participants