Skip to content

feat(t8s-cluster/workload-cluster): extract storageClasses from TeutonetesCloud#2004

Merged
cwrau merged 2 commits intomainfrom
feat/t8s-cluster/extract-storageclasses-from-cloud
Mar 11, 2026
Merged

feat(t8s-cluster/workload-cluster): extract storageClasses from TeutonetesCloud#2004
cwrau merged 2 commits intomainfrom
feat/t8s-cluster/extract-storageclasses-from-cloud

Conversation

@cwrau
Copy link
Copy Markdown
Member

@cwrau cwrau commented Feb 24, 2026

That way each cloud can define its own StorageClasses

Summary by CodeRabbit

  • Updates

    • Cloud integration API bumped to v1beta1 for improved compatibility.
  • Refactor

    • Storage classes are now rendered dynamically from cloud configuration rather than provided as static templates; legacy static storage definitions removed.

Copilot AI review requested due to automatic review settings February 24, 2026 15:40
@cwrau cwrau enabled auto-merge February 24, 2026 15:40
@gemini-code-assist
Copy link
Copy Markdown

Warning

Gemini encountered an error creating the summary. You can try again by commenting /gemini summary.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Updated the TeutonetesCloud lookup API version from v1alpha1 to v1beta1 in the OpenStack cluster template and replaced two static teutostack StorageClass templates with a new dynamic Helm template that generates StorageClass resources from the TeutonetesCloud spec.

Changes

Cohort / File(s) Summary
API Version Update
charts/t8s-cluster/templates/management-cluster/clusterClass/openStackClusterTemplate/_openStackClusterTemplateSpec.yaml
Bumped the TeutonetesCloud lookup API version from v1alpha1 to v1beta1.
Dynamic StorageClass Template
charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml
Added a Helm template that loads TeutonetesCloud, validates it, iterates volume type mappings, and renders StorageClass resources via a reusable fragment, including default-class handling and common labels.
Removed Static StorageClass Files
charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_hdd.yaml, charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_ssd.yaml
Deleted the previously static teutostack-hdd and teutostack-ssd StorageClass template definitions and their inclusion scaffolding.

Sequence Diagram(s)

sequenceDiagram
  participant Helm as Helm template renderer
  participant CR as TeutonetesCloud (CR)
  participant K8s as Kubernetes API

  Helm->>CR: lookup TeutonetesCloud (v1beta1)
  CR-->>Helm: return cloud spec (volumeTypes, defaults)
  Helm->>Helm: iterate volume type mappings, build StorageClass docs
  Helm->>K8s: apply generated StorageClass resources
  K8s-->>Helm: acknowledge resource creation
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • marvinWolff
  • teutonet-bot
  • tasches

Poem

🐰
I hopped through charts at break of day,
Swapped alpha for beta along the way,
Static seeds replaced by a dynamic spree,
Storage classes sprout where templates decree,
My whiskers twitch — deploy and hooray!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: extracting StorageClasses from TeutonetesCloud specification to allow per-cloud customization, which is reflected in all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/t8s-cluster/extract-storageclasses-from-cloud

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors storage class configuration by extracting it from hardcoded YAML files specific to TeutoStack into a dynamic system that reads storage class definitions from a TeutonetesCloud CRD. This enables different cloud providers to define their own storage classes via the CRD specification.

Changes:

  • Removed hardcoded TeutoStack-specific storage class definitions (ssd and hdd)
  • Added dynamic storage class generation based on TeutonetesCloud CRD's volumeTypes specification
  • Updated TeutonetesCloud API version from v1alpha1 to v1beta1 for consistency

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_ssd.yaml Deleted hardcoded SSD storage class definition
charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_hdd.yaml Deleted hardcoded HDD storage class definition
charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml Added dynamic storage class generation from TeutonetesCloud CRD volumeTypes
charts/t8s-cluster/templates/management-cluster/clusterClass/openStackClusterTemplate/_openStackClusterTemplateSpec.yaml Updated TeutonetesCloud API version to v1beta1

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml Outdated
Comment thread charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml Outdated
Comment thread charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml
Comment thread charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml
@cwrau cwrau force-pushed the feat/t8s-cluster/extract-storageclasses-from-cloud branch from 57c38c0 to 1c75f69 Compare February 24, 2026 15:48
tasches
tasches previously approved these changes Feb 24, 2026
…netesCloud

That way each cloud can define its own StorageClasses
@cwrau cwrau force-pushed the feat/t8s-cluster/extract-storageclasses-from-cloud branch from 1c75f69 to acaefad Compare February 24, 2026 16:04
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml (1)

28-32: availability: nova is hardcoded — consider sourcing it from the cloud spec.

All generated StorageClasses will unconditionally target the nova availability zone. If a TeutonetesCloud spec ever exposes per-volume-type availability zone data, this static value would need to be revisited. At minimum, document the assumption.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml` around
lines 28 - 32, The StorageClass template currently hardcodes availability: nova;
change it to read the availability zone from the cloud spec/Helm values (e.g. a
field like .Values.cloud.availability or a TeutonetesCloud spec value) and fall
back to "nova" only as a default, so generated StorageClasses target the
configured zone; update the template that sets the availability parameter and
document the assumption in chart values/README (reference the template
parameters `availability` and `type` and the StorageClass template) so future
per-volume-type availability data can be wired in.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml`:
- Around line 8-14: The template currently always calls include
"t8s-cluster.helm.resourceIntoCluster" even when $storageClasses is empty; add a
guard so you only call include "t8s-cluster.helm.resourceIntoCluster" when
$storageClasses is non-empty (e.g., wrap the include call in an {{- if
$storageClasses }} ... {{- end }}), keeping the existing logic that builds
$storageClasses from range $cloud.spec.volumeTypes.types and referencing the
same include "t8s-cluster.storageclass" items.
- Around line 17-23: The helper common.helm.labels is being called with an empty
dict so it cannot access .Release/.Chart; update the StorageClass template
("t8s-cluster.storageclass") to call the labels helper with the root chart
context (e.g. change include "common.helm.labels" (dict) to include
"common.helm.labels" $ | nindent 4) and ensure any callers that include
"t8s-cluster.storageclass" also forward the root context (pass $ when calling
include) so .Release and .Chart are available inside the helper; apply the same
change pattern to the other affected templates (certificates.yaml,
_policyTemplate.yaml, clusterissuer.yaml, ciliumNetworkPolicy.yaml) where
common.helm.labels or t8s-cluster.storageclass is invoked.

---

Nitpick comments:
In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml`:
- Around line 28-32: The StorageClass template currently hardcodes availability:
nova; change it to read the availability zone from the cloud spec/Helm values
(e.g. a field like .Values.cloud.availability or a TeutonetesCloud spec value)
and fall back to "nova" only as a default, so generated StorageClasses target
the configured zone; update the template that sets the availability parameter
and document the assumption in chart values/README (reference the template
parameters `availability` and `type` and the StorageClass template) so future
per-volume-type availability data can be wired in.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e558f0 and acaefad.

📒 Files selected for processing (4)
  • charts/t8s-cluster/templates/management-cluster/clusterClass/openStackClusterTemplate/_openStackClusterTemplateSpec.yaml
  • charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml
  • charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_hdd.yaml
  • charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_ssd.yaml
💤 Files with no reviewable changes (2)
  • charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_hdd.yaml
  • charts/t8s-cluster/templates/workload-cluster/storageclass/teutostack/teutostack_ssd.yaml

Comment thread charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml
Comment thread charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml
@cwrau cwrau enabled auto-merge February 25, 2026 13:20
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml (2)

11-17: Add a guard before calling resourceIntoCluster when $storageClasses is empty.

This was flagged in a previous review — wrapping the resourceIntoCluster call with {{- if $storageClasses }} avoids creating an empty HelmRelease when no volume types are defined.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml` around
lines 11 - 17, The template calls include "t8s-cluster.helm.resourceIntoCluster"
with ($storageClasses | join "\n---\n") even when $storageClasses is empty,
producing an empty HelmRelease; wrap that include call in a guard like {{- if
$storageClasses }} ... {{- end }} so the resourceIntoCluster invocation (the
include "t8s-cluster.helm.resourceIntoCluster" line) only runs when
$storageClasses has elements.

20-26: common.helm.labels receives an empty dict — .Release and .Chart are lost.

This was flagged in a previous review. When the context is overridden by passing a custom variable (e.g., (dict ...)), access to all default global objects (.Release, .Chart, .Values, etc.) is lost inside the called template. The common.helm.labels helper needs these to produce helm.sh/chart, app.kubernetes.io/managed-by, etc.

The fix requires forwarding the root context — either by adding a "context" key to the dict passed to t8s-cluster.storageclass at the call site (line 14) and then forwarding it into common.helm.labels, or by restructuring t8s-cluster.storageclass to accept a "context" key.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml` around
lines 20 - 26, The helper call to common.helm.labels inside the
t8s-cluster.storageclass template is given an empty dict which loses the root
Helm context (.Release, .Chart, .Values); update the include to forward the root
context so the helper can access those globals — e.g., change the include to
pass a dict containing "context": . (or simply pass .) so common.helm.labels
receives the original context; ensure t8s-cluster.storageclass forwards that
context into the include (or accept a "context" key and then pass it through) so
labels like helm.sh/chart and app.kubernetes.io/managed-by are generated
correctly.
🧹 Nitpick comments (2)
charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml (2)

20-38: Consider moving t8s-cluster.storageclass to a helpers file.

Defining named templates inside a rendered template file is valid Helm, but files whose name begins with an underscore are assumed to not have a manifest inside and are available everywhere within other chart templates for use — the conventional place for reusable define blocks. Moving t8s-cluster.storageclass to _helpers.tpl (or a dedicated _storageClasses.tpl) improves discoverability and keeps storageClasses.yaml focused on rendering logic.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml` around
lines 20 - 38, Move the reusable template definition named
"t8s-cluster.storageclass" out of the rendered manifest file and into a helpers
file (e.g., _helpers.tpl or a dedicated _storageClasses.tpl); update
storageClasses.yaml to call the define via include (keeping
rendering/manifest-only content there) so the define lives in the underscore
helpers file for discoverability and reuse, ensure the template name
"t8s-cluster.storageclass" is preserved and any callers use include
"t8s-cluster.storageclass" (or the new helper file) to render the StorageClass
manifest.

31-35: availability: nova is hardcoded — inconsistent with other availability zone configurations.

The chart exposes availabilityZone for cluster templates and bastion configuration, but the Cinder CSI StorageClass parameter hardcodes availability: nova. This creates inconsistency on non-standard OpenStack deployments with custom availability zones. Consider sourcing this from the TeutonetesCloud spec or making it configurable to align with the rest of the configuration pattern.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml` around
lines 31 - 35, The StorageClass hardcodes parameters.availability: nova which
breaks non-standard AZs; update the template to source availability from chart
values (e.g. use {{ .Values.availabilityZone }} or a namespaced value like {{
.Values.openstack.availabilityZone }}), add that key to values.yaml, and keep a
sensible default/fallback (e.g. fallback to "nova" if the value is empty) so
parameters.availability uses the configured availability zone instead of the
hardcoded "nova"; modify the parameters block in storageClasses.yaml (the
parameters.availability line) accordingly and ensure any related documentation
or README references the new values key.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml`:
- Around line 3-7: The template currently skips the fatal fail via the check on
.Release.Namespace which can silently mask real deployments to the "default"
namespace; change the guard on the fail in the storageClasses template to use an
explicit testing flag or the cloud value instead (e.g., check
.Values.global.testing == true OR test that .Values.cloud is empty) rather than
.Release.Namespace. Update the conditional around the fail (the block containing
fail (printf "Cloud %s not found" .Values.cloud)) to only bypass the fail when a
clear, intentional flag (.Values.global.testing) is set or when .Values.cloud is
empty, and add a brief comment explaining the bypass.

---

Duplicate comments:
In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml`:
- Around line 11-17: The template calls include
"t8s-cluster.helm.resourceIntoCluster" with ($storageClasses | join "\n---\n")
even when $storageClasses is empty, producing an empty HelmRelease; wrap that
include call in a guard like {{- if $storageClasses }} ... {{- end }} so the
resourceIntoCluster invocation (the include
"t8s-cluster.helm.resourceIntoCluster" line) only runs when $storageClasses has
elements.
- Around line 20-26: The helper call to common.helm.labels inside the
t8s-cluster.storageclass template is given an empty dict which loses the root
Helm context (.Release, .Chart, .Values); update the include to forward the root
context so the helper can access those globals — e.g., change the include to
pass a dict containing "context": . (or simply pass .) so common.helm.labels
receives the original context; ensure t8s-cluster.storageclass forwards that
context into the include (or accept a "context" key and then pass it through) so
labels like helm.sh/chart and app.kubernetes.io/managed-by are generated
correctly.

---

Nitpick comments:
In `@charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml`:
- Around line 20-38: Move the reusable template definition named
"t8s-cluster.storageclass" out of the rendered manifest file and into a helpers
file (e.g., _helpers.tpl or a dedicated _storageClasses.tpl); update
storageClasses.yaml to call the define via include (keeping
rendering/manifest-only content there) so the define lives in the underscore
helpers file for discoverability and reuse, ensure the template name
"t8s-cluster.storageclass" is preserved and any callers use include
"t8s-cluster.storageclass" (or the new helper file) to render the StorageClass
manifest.
- Around line 31-35: The StorageClass hardcodes parameters.availability: nova
which breaks non-standard AZs; update the template to source availability from
chart values (e.g. use {{ .Values.availabilityZone }} or a namespaced value like
{{ .Values.openstack.availabilityZone }}), add that key to values.yaml, and keep
a sensible default/fallback (e.g. fallback to "nova" if the value is empty) so
parameters.availability uses the configured availability zone instead of the
hardcoded "nova"; modify the parameters block in storageClasses.yaml (the
parameters.availability line) accordingly and ensure any related documentation
or README references the new values key.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between acaefad and 3664c8e.

📒 Files selected for processing (1)
  • charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml

Comment thread charts/t8s-cluster/templates/workload-cluster/storageClasses.yaml
@cwrau cwrau added this pull request to the merge queue Mar 11, 2026
Merged via the queue into main with commit 86570be Mar 11, 2026
32 checks passed
@cwrau cwrau deleted the feat/t8s-cluster/extract-storageclasses-from-cloud branch March 11, 2026 07:41
github-merge-queue Bot pushed a commit that referenced this pull request Mar 20, 2026
🤖 I have created a release *beep* *boop*
---


##
[9.7.0](t8s-cluster-v9.6.0...t8s-cluster-v9.7.0)
(2026-03-18)


### Features

* **t8s-cluster/workload-cluster:** extract storageClasses from
TeutonetesCloud
([#2004](#2004))
([86570be](86570be))


### Bug Fixes

* **t8s-cluster:** use plain values for autoScaling
([#2002](#2002))
([5a28b1a](5a28b1a))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants