Files
28892ccc7e Feat: implement valuesFrom support for helmchart component and update… (#7099)
* feat: implement valuesFrom support for helmchart component and update documentation examples

Signed-off-by: Anaswara Suresh <anaswarasuresh2212@gmail.com>

* fix: address cubic review feedback on valuesFrom

Three issues raised by cubic AI review on kubevela#7099:

1. docs/examples/helmchart-valuesfrom/secret-and-inline.yaml —
   Expected-result comments used incorrect paths (resources.cpu /
   resources.mem) and values (500m) that did not match the actual CM
   data. Rewrote the narrative to use the real paths
   (resources.limits.cpu / resources.limits.memory) and bundled the
   Secret inline in the manifest so the example is self-contained and
   the expected output is deterministic.

2. docs/examples/helmchart-valuesfrom/secret-and-inline.yaml —
   The Secret was marked optional: true while the narrative required
   it for the merged output to match. Bundled the Secret inline and
   dropped the optional flag, removing the order/timing ambiguity.
   README.md updated to drop the now-redundant "create the Secret
   first" instruction.

3. pkg/cue/cuex/providers/helm/helm.go:Render —
   After removing the unconditional "default" fallback for
   releaseNamespace, Helm could run with an empty namespace when both
   Context.AppNamespace and Release.Namespace were unset (non-normal
   code paths — direct callers, tests, CLI tooling). Restored the
   "default" fallback at the end of the namespace resolution while
   keeping the Application-namespace plumbing for tenant-scoped
   cross-namespace rejection.

Co-authored-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Signed-off-by: Anaswara Suresh <anaswarasuresh2212@gmail.com>

* feat: add valuesFrom fingerprinting for helmchart components to trigger workflow restarts on ConfigMap/Secret changes

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: add valuesFrom fingerprinting for helmchart components to trigger workflow restarts on ConfigMap/Secret changes

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: enhance valuesFrom support for helmchart components with fingerprinting and error handling

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* docs: clarify cross-namespace restrictions for valuesFrom in helmchart examples

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* ci: retrigger checks

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: add publishVersion support to Helm provider for stable release management

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: improve error handling for application retrieval in Helm provider

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* ci: retrigger checks

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

* feat: add application publishVersion lookup defense in Helm provider tests

Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>

---------

Signed-off-by: Anaswara Suresh <anaswarasuresh2212@gmail.com>
Signed-off-by: Ayush Kumar <ayushshyamkumar888@gmail.com>
Co-authored-by: Anaswara Suresh <anaswarasuresh2212@gmail.com>
2026-04-28 20:02:58 -07:00

128 lines
5.4 KiB
Markdown

# helmchart valuesFrom examples
The native `helmchart` component can merge values from `ConfigMap` and `Secret`
resources before rendering the chart. Useful for pulling per-environment config,
database DSNs, or any sensitive value out of the Application spec itself.
## Quick reference
```yaml
components:
- type: helmchart
properties:
chart:
source: podinfo
repoURL: https://stefanprodan.github.io/podinfo
version: "6.11.1"
release:
name: podinfo
namespace: myapp
values:
replicaCount: 3 # inline — wins over anything below
valuesFrom:
- kind: ConfigMap
name: podinfo-base # read first
- kind: Secret
name: podinfo-overlay # read second, overrides earlier on conflict
# key: values.yaml # optional, defaults to "values.yaml"
# optional: true # skip silently on not-found
```
## Merge order
Highest priority wins:
```
inline `values` > valuesFrom[N] > valuesFrom[N-1] > ... > valuesFrom[0] > chart defaults
```
- **Deep-merge** for map keys (e.g. `resources.limits.memory`)
- **Replace** for arrays (e.g. `extraArgs: [...]` from a later source replaces earlier)
- `null` values are preserved (not treated as a delete marker)
## Semantics you should know
| Field | Default | Notes |
|--------------|--------------------------------|------------------------------------------------------------|
| `kind` | — | Only `Secret` and `ConfigMap` are supported. |
| `name` | — | Required. |
| `namespace` | Chart release namespace (which itself defaults to the Application's own namespace when `release.namespace` is unset) | Cross-namespace references are **rejected** by design — the explicit value must equal either the release namespace or the Application's own namespace. |
| `key` | `values.yaml` | Which key inside `.data` holds the YAML blob. |
| `optional` | `false` | When `true`, missing resource/key is skipped silently. Parse errors and permission errors still fail. |
### Cross-namespace is disallowed
Because the KubeVela controller has cluster-wide read on ConfigMaps and Secrets,
allowing an arbitrary user-supplied `namespace` would let any tenant read
arbitrary Secrets. An explicit `valuesFrom.namespace` is therefore accepted
only if it matches one of:
- the **chart release namespace** (`release.namespace`, the default), or
- the **Application's own namespace** (`metadata.namespace` on the
`Application` object).
When `release.namespace` is unset it falls back to the Application's namespace,
so the two are equal in the common single-namespace case. They diverge when a
user explicitly puts the chart in a different namespace from the App; both
options remain valid for the source.
Anything else fails with:
```
cross-namespace valuesFrom sources are not permitted
```
If you need shared config across unrelated namespaces, copy the ConfigMap into
each Application namespace (e.g. via a replicator) rather than referencing
across.
### External CM/Secret edits propagate on the next reconcile
An edit to a referenced `ConfigMap` or `Secret` does not directly trigger a
reconcile, but on the next reconcile (periodic resync, default ~5 minutes) the
controller computes a content fingerprint of every referenced source and folds
it into `desiredRev` as a `-vf-…` suffix on `status.workflow.appRevision`. When
the content moves, the suffix moves, the workflow gate fails, the workflow
restarts, and the chart re-renders with the new values.
To roll out immediately rather than waiting for the next resync, touch the
`app.oam.dev/requestreconcile` annotation on the Application:
```bash
kubectl -n myapp annotate app foo app.oam.dev/requestreconcile=$(date +%s) --overwrite
```
Caveats:
- **Cosmetic-only edits do not roll out.** YAML→JSON canonicalisation (matching
Helm's own value-comparison contract) drops whitespace, comments, and key
order, so an edit that adds a comment or reformats produces the same digest.
- **A rollback to identical earlier content does not roll out**, for the same
reason.
- **`publishVersion` annotation pin**: when `app.oam.dev/publishVersion` is set,
the suffix is **not** appended. The pin is hard — CM/Secret edits are
deferred until the user bumps the pin.
- **Multi-cluster**: `valuesFrom` sources are always read from the
control-plane cluster, regardless of where the chart is deployed (e.g. via a
topology policy). A CM/Secret living only on a target member cluster will not
be found.
- **Optional missing sources** contribute a stable `<missing>` sentinel to the
fingerprint, so they do not cause spurious upgrades while absent and
deterministically move the digest the moment they appear.
## Files in this folder
- [`configmap-backed.yaml`](./configmap-backed.yaml) — a minimal example with
one ConfigMap backing `replicaCount`.
- [`secret-and-inline.yaml`](./secret-and-inline.yaml) — three-layer merge:
chart defaults → ConfigMap → Secret → inline.
Each file is self-contained (the ConfigMap/Secret is bundled alongside the
Application). Apply with:
```bash
kubectl apply -f configmap-backed.yaml
# or
kubectl apply -f secret-and-inline.yaml
```