Skip to content

feat: add helm_lib_api_version_exists and grant VRR RBAC to csi provisioner - #207

Merged
duckhawk merged 1 commit into
mainfrom
feat/storage-foundation-compat
Aug 6, 2026
Merged

feat: add helm_lib_api_version_exists and grant VRR RBAC to csi provisioner#207
duckhawk merged 1 commit into
mainfrom
feat/storage-foundation-compat

Conversation

@duckhawk

@duckhawk duckhawk commented Aug 6, 2026

Copy link
Copy Markdown
Member

Overview

Preparation for the migration of CSI modules from snapshot-controller to storage-foundation.

Two changes, charts/helm_lib version bumped to 1.72.13:

  1. New define helm_lib_api_version_exists (_api_version_and_kind.tpl) — returns "true" when a <group>/<version>/<Kind> is available, checking two sources:

    • .Values.global.discovery.apiVersions — GVKs collected by deckhouse from the crds/ directories of enabled modules and put into global values (a change there re-renders every module, so gates built on this helper open without manual action once the CRD provider is enabled);
    • .Capabilities.APIVersions — real cluster discovery, which also covers CRDs installed outside a deckhouse module (by hand, by a third-party operator, by vanilla external-snapshotter).

    The existing helm_lib_kind_exists is left untouched and is not reused: it fails on empty capabilities, ignores global.discovery.apiVersions and matches the kind by suffix without the API group.

  2. VolumeRestoreRequest RBAC in helm_lib_csi_controller_rbac — gated on the presence of storage-foundation.deckhouse.io/v1alpha1/VolumeRestoreRequest, the provisioner ClusterRole additionally gets:

    - apiGroups: ["storage-foundation.deckhouse.io"]
      resources: ["volumerestorerequests"]
      verbs: ["get", "list", "watch"]
    - apiGroups: [""]
      resources: ["persistentvolumeclaims"]
      verbs: ["create", "patch"]

Why the VRR rules belong here

When storage-foundation is enabled, helm_lib_csi_image_with_common_fallback replaces all CSI sidecars with the storage-foundation forks. The forked external-provisioner additionally runs the VolumeRestoreRequest executor: a cluster-wide informer on volumerestorerequests that provisions the target volume and creates the PV/PVC pair for it. The sidecar is deployed by the driver module, so its csi ServiceAccount needs those permissions in every module that uses this define — including modules without snapshot support, since the executor lives in the provisioner sidecar, not in the snapshotter one.

Today these permissions are handed out by the storage-foundation hook 040-vrr-provisioner-rbac from a hardcoded namespace list containing a single d8-sds-local-volume, which leaves the other modules with a 403 loop on the informer (reproduced in csi-nfs). storage-foundation itself marks the hook a workaround. Static rules in lib-helm replace it: the hook is to be removed once this version is synced into deckhouse for the in-tree cloud providers.

Notes:

  • volumerestorerequests/status is deliberately not granted. The status is set by the storage-foundation VRR controller from the state of the target PVC; the sidecar only executes, so it cannot fabricate a Ready status.
  • volumecapturerequests are not granted either — VCRs are reconciled by the storage-foundation controller alone; the module's csi-snapshotter sidecar only needs the stock external-snapshotter role from this same define.
  • The PVC rule complements the stock one (get/list/watch/update) up to get/list/watch/create/update/patch — the set the storage-foundation hook grants.
  • RBAC rules referring to a non-existent CRD are harmless, so the gate here is about consistency with the module templates that will use the same helper, not about correctness. The ordering is safe anyway: VRR CRDs arrive together with storage-foundation being enabled, and the same global.discovery.apiVersions change re-renders the module, so the rules appear no later than the provisioner image is swapped for the fork.

Tests

  • New suite tests/tests/helm_lib_api_version_exists_test.yaml: GVK only in global.discovery.apiVersions, only in Capabilities, in neither, and empty capabilities (returns a value without failing).
  • helm_lib_csi_controller_rbac suite extended with the CRD-present / CRD-absent cases; its test template now passes global.discovery and Capabilities in the context.
  • make ci/tests/unit — 358 tests, all green. make doc/diff — clean (charts/helm_lib/README.md regenerated).

For consumers of this helper

Templates that gate on the snapshot stack should use the marker GVK snapshot.storage.k8s.io/v1/VolumeSnapshotClass instead of .Values.global.enabledModules | has "snapshot-controller", so that the gate does not depend on which module provides the CRDs:

{{- if (include "helm_lib_api_version_exists" (list . "snapshot.storage.k8s.io/v1/VolumeSnapshotClass")) }}

…sioner

Adds `helm_lib_api_version_exists` — a CRD-presence check over two sources:
`.Values.global.discovery.apiVersions` (GVKs from the `crds/` directories of
enabled modules, refreshed by deckhouse in global values) and
`.Capabilities.APIVersions` (real cluster discovery, which also covers CRDs
installed outside of a deckhouse module). Unlike the existing
`helm_lib_kind_exists`, it matches the full group/version/kind, does not fail on
empty capabilities and takes `global.discovery.apiVersions` into account, so it
is usable as a template gate for optional CRDs.

Uses it in `helm_lib_csi_controller_rbac`: when the
`storage-foundation.deckhouse.io/v1alpha1/VolumeRestoreRequest` CRD is present,
the provisioner ClusterRole additionally grants read access to
volumerestorerequests and create/patch on persistentvolumeclaims. With
storage-foundation enabled, the stock external-provisioner sidecar is replaced
with its fork, which runs the VolumeRestoreRequest executor under the module's
`csi` ServiceAccount; without these permissions the sidecar gets 403 on the
volumerestorerequests informer in every module that deploys it.
volumerestorerequests/status is deliberately not granted — the status is owned
by the storage-foundation controller.

Signed-off-by: v.oleynikov <vasily.oleynikov@flant.com>
@duckhawk
duckhawk merged commit 9030285 into main Aug 6, 2026
4 checks passed
@duckhawk
duckhawk deleted the feat/storage-foundation-compat branch August 6, 2026 14:27
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.

2 participants