mirror of
https://github.com/cozystack/cozystack.git
synced 2026-10-29 16:17:20 +09:00
fix(tenant): render the chart without the platform's injected values
`helm lint packages/apps/tenant` fails, and two of its three errors are
the chart's own.
`templates/keycloakgroups.yaml` reads `index .Values._cluster
"oidc-enabled"`. `_cluster` is injected by the platform, so it is absent
whenever the chart is rendered on its own, and `index` on a nil map is a
hard error: `index of untyped nil`. The chart cannot be rendered or
linted outside a cluster at all.
The idiom the neighbouring charts use for the same lookup does not
rescue this on its own, which is worth stating because it looks like it
does. `(index .Values._cluster "x") | default "y"` still errors: `index`
evaluates first and fails on the nil map, so `default` never sees a
result to substitute; it only ever covered a key missing from a map that
exists.
The spelling alone does not decide whether a chart breaks, though.
`packages/system/cozystack-basics` uses it and lints clean, because line
1 of its values.yaml is `_cluster: {}`, which makes the map non-nil
before `index` runs. So a chart is broken only when it neither declares
the empty map nor guards at the use site. Guarding at the use site is
preferred here because it makes the template correct whatever
values.yaml contains, which is what lets the chart render standalone;
and `_cluster` is platform-internal, while this chart's values.yaml,
schema and README are generated together from
api/apps/v1alpha1/tenant/types.go as user-facing output.
The guard has to sit on the map rather than on the value it returns,
hence `index (.Values._cluster | default dict) "oidc-enabled"`.
That is behaviour-preserving rather than merely quieter. With `_cluster`
present, `| default dict` returns it untouched and the lookup is what it
was. With it absent the lookup is nil, the `eq` below is false, and the
block stays unrendered, which is what an unconfigured tenant should
produce. Rendered both ways before and after, with
`--api-versions v1.edp.epam.com/v1` so the capability-gated block
actually executes, the output is identical byte for byte: four
KeycloakRealmGroups when `oidc-enabled` is `"true"`, none when it is
`"false"`. Rendering with no values at all goes from a hard error to a
clean render with no groups.
`Chart.yaml` also does not declare `cozy-lib`, which is present as a
symlink under `charts/`, so lint reports missing chart metadata. Declare
it the way `packages/apps/qdrant` does, that being the one chart in the
tree that declares it and does not carry this error. Rendering is
unchanged by the declaration, checked the same way.
`tests/keycloakgroups_oidc_test.yaml` pins all three branches of the
gate: four realm groups when `oidc-enabled` is `"true"`, none when it is
`"false"`, and none when the platform injected no `_cluster` at all.
That third case is the one the guard exists for, and it needs no mock,
because `_cluster` is absent from values.yaml and so "not injected" is
simply the chart's own default state. Against the unguarded template the
suite fails with `index of untyped nil`; the chart's other seven suites
pass identically either way, which is what left the change uncovered.
The third error, `invalid icon URL '/logos/tenant.svg'`, is deliberately
left. Lint wants a URL with a scheme, and all 31 charts in the tree that
carry an icon use a relative path, none an absolute one. Changing this
one would make it the only chart with a different convention, and
choosing the URL a relative path should become is a decision about where
those assets are served from, not about lint.
Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
This commit is contained in:
3 files changed
+65
-1
No files matched your search
@@ -4,3 +4,7 @@ description: Separated tenant namespace
|
||||
icon: /logos/tenant.svg
|
||||
type: application
|
||||
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
|
||||
dependencies:
|
||||
- name: cozy-lib
|
||||
version: "*"
|
||||
repository: "file://charts/cozy-lib"
|
||||
@@ -1,4 +1,11 @@
|
||||
{{- $oidcEnabled := index .Values._cluster "oidc-enabled" }}
|
||||
{{- /* _cluster is injected by the platform, so it is absent whenever the chart
|
||||
is rendered on its own, as `helm lint` and `helm template` do. `index`
|
||||
errors on a nil map before any `| default` on its result can apply, so
|
||||
the guard has to sit on the map rather than on the looked-up value. With
|
||||
_cluster present this yields exactly what indexing it directly yielded;
|
||||
with it absent the lookup is nil and the block below stays unrendered,
|
||||
which is what an unconfigured tenant should produce. */ -}}
|
||||
{{- $oidcEnabled := index (.Values._cluster | default dict) "oidc-enabled" }}
|
||||
{{- if eq $oidcEnabled "true" }}
|
||||
{{- if .Capabilities.APIVersions.Has "v1.edp.epam.com/v1" }}
|
||||
apiVersion: v1.edp.epam.com/v1
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
suite: tenant keycloak realm groups — the oidc gate survives an uninjected _cluster
|
||||
templates:
|
||||
- templates/keycloakgroups.yaml
|
||||
|
||||
# `_cluster` is injected by the platform, so it is simply absent whenever the
|
||||
# chart is rendered on its own: `helm lint`, `helm template`, and this suite.
|
||||
# The template reads it with `index`, and `index` on a nil map is a hard error
|
||||
# rather than an empty result, so before the guard the chart could not be
|
||||
# rendered outside a cluster at all.
|
||||
#
|
||||
# The guard has to sit on the map, not on the value: the spelling used
|
||||
# elsewhere in the tree, `(index .Values._cluster "x") | default "y"`, does not
|
||||
# help, because `index` is evaluated first and fails before `default` ever sees
|
||||
# a result to substitute.
|
||||
#
|
||||
# The third case below is the one that pins the fix. It carries no `set:` at
|
||||
# all, because `_cluster` is absent from values.yaml, so "the platform injected
|
||||
# nothing" needs no mocking — it is just the chart's own default state.
|
||||
|
||||
release:
|
||||
name: tenant-alice
|
||||
namespace: tenant-alice
|
||||
|
||||
capabilities:
|
||||
apiVersions:
|
||||
- v1.edp.epam.com/v1
|
||||
|
||||
tests:
|
||||
- it: renders the four realm groups when oidc is enabled
|
||||
set:
|
||||
_cluster:
|
||||
oidc-enabled: "true"
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 4
|
||||
|
||||
- it: renders nothing when oidc is explicitly disabled
|
||||
# The gate is an equality against the string "true", so anything else is
|
||||
# off. Pinned alongside the enabled case so a guard that accidentally
|
||||
# rendered unconditionally would be caught.
|
||||
set:
|
||||
_cluster:
|
||||
oidc-enabled: "false"
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
|
||||
- it: renders nothing when the platform injected no _cluster at all
|
||||
# Fails with `index of untyped nil` without the guard. This is the case the
|
||||
# fix exists for, and the reason the chart can now be rendered standalone.
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
Reference in new issue
Block a user