{"id":50881796,"url":"https://github.com/validatedpatterns/vp-sscsi-spc-chart","last_synced_at":"2026-06-15T13:31:20.939Z","repository":{"id":356115475,"uuid":"1231016026","full_name":"validatedpatterns/vp-sscsi-spc-chart","owner":"validatedpatterns","description":"Library chart to make it easier to include secretproviderclasses for SS-CSI","archived":false,"fork":false,"pushed_at":"2026-05-06T18:16:10.000Z","size":18,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T18:36:46.951Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go Template","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/validatedpatterns.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-06T14:42:01.000Z","updated_at":"2026-05-06T18:15:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/validatedpatterns/vp-sscsi-spc-chart","commit_stats":null,"previous_names":["validatedpatterns/vp-sscsi-spc-chart"],"tags_count":4,"template":false,"template_full_name":"validatedpatterns/vp-template-chart","purl":"pkg:github/validatedpatterns/vp-sscsi-spc-chart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/validatedpatterns%2Fvp-sscsi-spc-chart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/validatedpatterns%2Fvp-sscsi-spc-chart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/validatedpatterns%2Fvp-sscsi-spc-chart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/validatedpatterns%2Fvp-sscsi-spc-chart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/validatedpatterns","download_url":"https://codeload.github.com/validatedpatterns/vp-sscsi-spc-chart/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/validatedpatterns%2Fvp-sscsi-spc-chart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34365596,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-15T13:31:18.251Z","updated_at":"2026-06-15T13:31:20.926Z","avatar_url":"https://github.com/validatedpatterns.png","language":"Go Template","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vp-sscsi-spc\n\n![Version: 0.1.13](https://img.shields.io/badge/Version-0.1.13-informational?style=flat-square)\n\nLibrary chart for app-level Vault SecretProviderClass rendering with hub, spoke, and external Vault support. Cluster CA material is managed by a separate cluster-wide chart.\n\n### Notable changes\n\n* v0.1.13: Remove the cluster: key entirely as the prefix for roles should always be either \"hub\" or **`global.cclusterDomain`** (for spokes), and we know which we are dealing with based on clusterGroup.\n* v0.1.12: On **spoke** clusters, `spec.parameters.vaultKubernetesMountPath` is **`global.clusterDomain`** (FQDN **without** `apps.`), not **`global.localClusterDomain`**. It remains **`hub`** when **`global.localClusterDomain == global.hubClusterDomain`**. Hub clusters are unchanged.\n* v0.1.12: On **spoke** clusters, `spec.parameters.vaultKubernetesMountPath` is **`global.clusterDomain`** (FQDN **without** `apps.`), not **`global.localClusterDomain`**. It remains **`hub`** when **`global.localClusterDomain == global.hubClusterDomain`**. Hub clusters are unchanged.\n* v0.1.11: On **spoke** clusters, default Kubernetes `roleName` uses **`global.clusterDomain`** (`\u003cclusterDomain\u003e-role` and `\u003cclusterDomain\u003e-sscsi-\u003croleSlug\u003e`), matching openshift-external-secrets. On the **hub**, computed roles remain **`hub-role`** and **`hub-sscsi-\u003croleSlug\u003e`** (always the **`hub`** prefix). If `global.clusterDomain` is empty on a spoke, the role prefix falls back to the computed mount path.\n* v0.1.9: Spoke `SecretProviderClass` no longer treats `clusterGroup.applications` entries with `chart: hashicorp-vault` as hub-style auth (which forced `vaultKubernetesMountPath: hub` when `global.localClusterDomain` was unset). Hub clusters keep hub-style mount logic.\n* v0.1.8: Added arbitrary Vault connection/auth configuration through values:\n  `vault.externalAddress` for custom endpoints, `auth.method` for selecting the\n  provider auth type, and `auth.extraParameters` to pass provider-specific auth\n  fields (for example JWT/AppRole/token). Kubernetes defaults remain unchanged,\n  including hub/spoke role-name conventions based on `hub` and\n  `global.clusterDomain`.\n\nThis chart is the **library for `SecretProviderClass` only**, **one dependency per application chart** that consumes Vault via SSCSI.\n\n**Vault CSI provider DaemonSet and TLS trust on the provider** (for example projected proxy cluster CA) are installed by **`openshift-sscsi-vault`** (chart **0.2.0+**), not this library. The legacy **`vp-vault-csi-provider`** chart is superseded by **`openshift-sscsi-vault`** for new installs.\n\n### Scope\n\nThis chart renders **only** `SecretProviderClass` YAML (named templates or optional `installDefaultManifests`). Use it from application charts that need:\n\nHub vs spoke detection compares **`global.localClusterDomain`** to **`global.hubClusterDomain`** only.\nPer **`validatedpatterns/clustergroup-chart`** (`values.schema.json` on **main**), **`global.localClusterDomain`** and **`global.hubClusterDomain`** are the cluster FQDN **with** the **`apps.`** component (framework-set), and **`global.clusterDomain`** is the same cluster FQDN **without** **`apps.`** — also framework-set.\nOn spokes, **`spec.parameters.vaultKubernetesMountPath`** and default Kubernetes **`roleName`** prefixes both use **`global.clusterDomain`** (not **`localClusterDomain`**), except the mount path becomes **`hub`** when **`localClusterDomain == hubClusterDomain`**.\n\n- Hub-cluster Vault auth (defaults `vaultKubernetesMountPath` to `hub` when `global.localClusterDomain == global.hubClusterDomain`, else `global.clusterDomain`; optional `vault.hubMountPath` override, hub role)\n- Spoke-cluster auth to centralized Vault (`global.clusterDomain` as `vaultKubernetesMountPath`, or **`hub`** when `global.localClusterDomain == global.hubClusterDomain`; default Kubernetes `roleName` on spokes uses **`global.clusterDomain`** as the prefix — hub clusters keep **`hub`** / **`hub-role`**)\n- External Vault endpoint override (`vault.externalAddress`)\n- Auth method override via values (`auth.method`, default `kubernetes`) plus pass-through auth parameters (`auth.extraParameters`) for non-kubernetes schemes\n- Optional reference to a pre-mounted CA path (`tls.vaultCACertPath`), or **`tls.projectedClusterCa.enabled: true`** to derive the path for **openshift-sscsi-vault**'s projected CNO/proxy bundle (same defaults as that chart's `syncProviderCaConfigMap`)\n- Optional app-key driven workload auth lookup from `clusterGroup.applications[*].ssCsiWorkloadAuth`\n\nThis chart does not install the CSI provider or mount trust bundles. Either set **`tls.vaultCACertPath`** explicitly, or enable **`tls.projectedClusterCa`** so **`spec.parameters.vaultCACertPath`** points at **`/etc/pki/vault-ca/ca-bundle.crt`** (CNO-injected proxy/cluster bundle) or **`.../vault-tls-ca.pem`** when **`injectTrustedCabundle: false`**, matching **openshift-sscsi-vault** defaults. Named template **`vp_sscsi_spc.projectedVaultCACertPath`** returns that path for custom includes.\n\n### Usage from parent charts\n\nMerge values into this chart shape (`ocpSecretsStoreCsiVault`, `global`, `clusterGroup`) and include:\n\n```yaml\n{{- $spcCtx := dict \"Chart\" $sc.Chart \"Capabilities\" $sc.Capabilities \"Release\" $sc.Release \"Values\" $spcVals }}\n{{- include \"vp_sscsi_spc.secretproviderclass\" $spcCtx }}\n\n```\n\nFor standalone rendering during development/tests, set:\n\n```yaml\nocpSecretsStoreCsiVault:\n  secretProviderClass:\n    installDefaultManifests: true\n```\n\nWhen `ocpSecretsStoreCsiVault.applicationKey` is set, the chart reads\n`clusterGroup.applications[applicationKey]` and can derive:\n\n- `metadata.namespace` from app namespace (fallback: release namespace)\n- `spec.parameters.roleName` from `ssCsiWorkloadAuth`: explicit `roleName`/`role`, or on the hub **`hub-sscsi-\u003croleSlug\u003e`** / **`hub-role`**, on spokes **`global.clusterDomain-sscsi-\u003croleSlug\u003e`** / **`global.clusterDomain-role`** (spoke fallback to mount path if `clusterDomain` is empty). `vaultKubernetesMountPath` on spokes is **`global.clusterDomain`** (or **`hub`** when local and hub domains match)\n\nFor `auth.method: kubernetes` (default), this chart emits `vaultKubernetesMountPath` and `roleName`.\nFor other auth methods, set `auth.method` and provide the provider-specific fields in `auth.extraParameters`.\n\n### Argo CD ignoreDifferences recommendation\n\nFor Argo CD applications that deploy the cluster-wide provider chart used with this library (for example `openshift-sscsi-vault`), add an `ignoreDifferences` block for the provider CA ConfigMap. This follows the pattern used in `~/gitwork/multicloud-gitops` (`values-hub.yaml`, `values-group-one.yaml`), where CNO/proxy bundle injection mutates `.data` after apply.\n\n```yaml\nignoreDifferences:\n  - group: \"\"\n    kind: ConfigMap\n    name: openshift-sscsi-vault-vault-tls-ca\n    namespace: vault\n    jsonPointers:\n      - /data\n    jqPathExpressions:\n      - .data\nsyncPolicy:\n  syncOptions:\n    - RespectIgnoreDifferences=true\n```\n\nIf you are using proxy/cluster CA bundle injection, the `vp-cluster-truster` application (for example `vp-manage-proxy-cluster-ca`) is the common way to manage `Proxy.spec.trustedCA` and the source bundle workflow. It is recommended in that setup so the injected bundle exists consistently.\n\nIf you are not using bundle injection and instead provide `tls.vaultCACertPath` from another trust source, `vp-cluster-truster` is not mandatory for this chart.\n\n### Workload timeouts, mount readiness, and retries\n\nApplication charts that combine this library with **CSI Secret Provider** mounts, **ConfigMaps**, and **projected** trust bundles should plan for **slow or stuck volume setup** and for **data that exists in API but is not yet usable** on disk. The following applies to **Deployments**, **ReplicaSets** (via the parent Deployment), **Pods**, **Jobs**, **CronJobs**, **StatefulSets**, and **DaemonSets** wherever a Pod template is defined.\n\n**What blocks `ContainerCreating`**\n\n- A **ConfigMap object that exists** usually mounts quickly. Long `ContainerCreating` is more often **image pull**, **scheduling**, or **volume plugins**. **`secrets-store.csi.k8s.io`** mounts can wait on Vault, credentials, or the network.\n- **Wrong or incomplete ConfigMap or secret file content** often still completes the mount; failure appears **after** the main container starts unless you **validate earlier** (see below).\n- **Liveness and readiness probes** run only **after** the container is running; they do not resolve infinite `ContainerCreating`.\n\n**Fail fast on required files (recommended)**\n\nFor any workload with a Pod template, add an **init container** (same volumes, minimal image) that checks required paths under the CSI mount, ConfigMap mount, or projected CA path, and **`exit 1`** if anything required is missing or invalid. Optionally wrap checks with a **shell `timeout`** so the init step cannot hang indefinitely. This gives clear failures and works well with **Job `backoffLimit`** or external orchestration retries.\n\n**Kubernetes time limits by resource**\n\n| Goal | Knob |\n|------|------|\n| Rollout stuck (new Pods not becoming Ready) | **Deployment `spec.progressDeadlineSeconds`** |\n| Cap total time for a **Job** | **Job `spec.activeDeadlineSeconds`**, plus **`spec.backoffLimit`** for retries |\n| Bound each **Pod** attempt | **Pod `spec.activeDeadlineSeconds`** (in the Pod template) |\n| CronJob run must not start too late after schedule | **CronJob `spec.startingDeadlineSeconds`** |\n\n**ReplicaSet**: do not tune deadlines on the ReplicaSet directly; set them on the owning **Deployment** (or higher-level controller).\n\n**StatefulSet and DaemonSet**: there is no **`progressDeadlineSeconds`**. Use **Pod `activeDeadlineSeconds`**, **init validation**, and probes (**`startupProbe`** helps slow-but-finite application start, not stuck pre-run mounts).\n\n**CSI and projected volumes**\n\n- Mount and retry behavior is **driver- and provider-specific**; use provider documentation for timeouts and failure modes in addition to the Kubernetes fields above.\n- **`optional: true`** on a **projected** `configMap` source avoids hard failure when that source is absent but can hide “trust bundle not ready”; pair **`optional`** with **init validation** when the file is required for Vault or TLS.\n\n**Argo**\n\n- **Argo CD** reflects **resource health** (for example Deployment **`ProgressDeadlineExceeded`**, Pods not Ready). It does not add volume timeouts; encode limits and checks in the manifests your Application syncs.\n- **Argo Workflows**: use **template `timeout`** and **`retryStrategy`** on steps so a bounded Pod or Job attempt can fail and retry at the workflow layer.\n\n## Values\n\n| Key | Type | Default | Description |\n|-----|------|---------|-------------|\n| clusterGroup.applications | object | `{}` |  |\n| global | object | `{\"clusterDomain\":\"foo.example.com\",\"hubClusterDomain\":\"hub.example.com\",\"localClusterDomain\":\"\"}` | Global values aligned with openshift-external-secrets chart patterns |\n| global.clusterDomain | string | `\"foo.example.com\"` | Vault Kubernetes auth role prefix on spokes (`\u003cclusterDomain\u003e-role`, `\u003cclusterDomain\u003e-sscsi-\u003cslug\u003e`). In validated patterns this matches **clustergroup-chart** `global.clusterDomain`: cluster FQDN **without** the `apps.` component (framework-set). See `localClusterDomain` for the apps form. |\n| global.hubClusterDomain | string | `\"hub.example.com\"` | Hub Vault route host suffix (`vault-vault.\u003chubClusterDomain\u003e`). Use the apps/API ingress form (for example `apps.hub.example.com`), same style as localClusterDomain. |\n| global.localClusterDomain | string | `\"\"` | Apps/API ingress FQDN (with `apps.`). Compared to `hubClusterDomain` for hub vs spoke detection; when equal to `hubClusterDomain`, spoke `vaultKubernetesMountPath` is `hub`. Spoke mount path is otherwise `global.clusterDomain` (without `apps.`), not this field. |\n| ocpSecretsStoreCsiVault | object | see nested keys | Settings for app-level SecretProviderClass rendering |\n| ocpSecretsStoreCsiVault.applicationKey | string | `\"\"` | Optional key under `clusterGroup.applications` used to resolve workload auth attributes (`ssCsiWorkloadAuth`). |\n| ocpSecretsStoreCsiVault.auth.extraParameters | object | `{}` | Extra auth parameters merged into `spec.parameters` for non-kubernetes methods (for example AppRole, JWT, token). Keys/values are passed through as provided. |\n| ocpSecretsStoreCsiVault.auth.method | string | `\"kubernetes\"` | Vault auth method for SecretProviderClass `spec.parameters.authType`. Defaults to `kubernetes`. |\n| ocpSecretsStoreCsiVault.auth.roleName | string | `\"hub-role\"` | Vault Kubernetes auth role name for hub-style auth (used when `auth.method` is `kubernetes`). |\n| ocpSecretsStoreCsiVault.objects | list | example placeholder; replace with your paths | KV objects to expose as files under the CSI mount (Vault CSI `objects` list) |\n| ocpSecretsStoreCsiVault.secretObjects | list | `[]` | Optional: sync mounted objects into native Kubernetes Secrets (CSI `secretObjects`) |\n| ocpSecretsStoreCsiVault.secretProviderClass.enabled | bool | `true` | When true, render SecretProviderClass manifests from this chart. |\n| ocpSecretsStoreCsiVault.secretProviderClass.installDefaultManifests | bool | `false` | When true, render default SPC manifests from `templates/install-default-manifests.yaml`. |\n| ocpSecretsStoreCsiVault.secretProviderClass.name | string | `\"vault-hub-secrets\"` | metadata.name of the SecretProviderClass (referenced from pod volumeAttributes) |\n| ocpSecretsStoreCsiVault.secretProviderClass.namespace | string | `\"\"` | Namespace where the SecretProviderClass is created |\n| ocpSecretsStoreCsiVault.tls | object | `{\"projectedClusterCa\":{\"enabled\":false,\"injectTrustedCabundle\":true,\"keyInConfigMap\":\"vault-tls-ca.pem\",\"mountDir\":\"/etc/pki/vault-ca\",\"trustedCabundleDataKey\":\"ca-bundle.crt\"},\"vaultCACertPath\":\"\",\"vaultSkipTLSVerify\":\"false\",\"vaultTLSServerName\":\"\"}` | TLS options for the Vault CSI provider. This chart only references an existing trust path and does not create CA material. |\n| ocpSecretsStoreCsiVault.tls.projectedClusterCa | object | `{\"enabled\":false,\"injectTrustedCabundle\":true,\"keyInConfigMap\":\"vault-tls-ca.pem\",\"mountDir\":\"/etc/pki/vault-ca\",\"trustedCabundleDataKey\":\"ca-bundle.crt\"}` | When `enabled` is true and `vaultCACertPath` is empty, set `vaultCACertPath` to the bundle file under **openshift-sscsi-vault** defaults (CNO proxy merge `ca-bundle.crt` vs PEM `vault-tls-ca.pem`). Align these fields with `ocpSecretsStoreCsiVault.caProvider.syncProviderCaConfigMap` on that chart. |\n| ocpSecretsStoreCsiVault.tls.vaultCACertPath | string | `\"\"` | Explicit PEM path on the CSI provider pod. When non-empty, wins over `projectedClusterCa`. |\n| ocpSecretsStoreCsiVault.vault.externalAddress | string | `\"\"` | If non-empty, used as `spec.parameters.vaultAddress` (external Vault endpoint). |\n| ocpSecretsStoreCsiVault.vault.hubMountPath | string | `\"\"` | Optional override for hub-style `vaultKubernetesMountPath`. Empty defaults to `hub` when `global.localClusterDomain == global.hubClusterDomain`, else `global.clusterDomain`. |\n| ocpSecretsStoreCsiVault.workloadAuthIndex | int | `0` | Index into `clusterGroup.applications[applicationKey].ssCsiWorkloadAuth` when multiple entries are present. |\n\n----------------------------------------------\nAutogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvalidatedpatterns%2Fvp-sscsi-spc-chart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvalidatedpatterns%2Fvp-sscsi-spc-chart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvalidatedpatterns%2Fvp-sscsi-spc-chart/lists"}