Skip to content

Conversation

@kvaps
Copy link
Member

@kvaps kvaps commented Jan 2, 2026

What this PR does

Replaces Helm lookup functions with FluxCD valuesFrom mechanism for passing configuration to HelmReleases. This provides cleaner config propagation and eliminates the need for force reconcile controllers.

Changes:

Platform/Tenant charts:

  • Add Secret cozystack-values creation in platform chart (for tenant-root and system namespaces)
  • Add Secret cozystack-values creation in tenant chart (for child namespaces)

cozystack-api:

  • Add valuesFrom references to HelmRelease when creating applications
  • Filter keys starting with _ when returning Application specs
  • Validate that user values don't contain _ prefixed keys

cozystack-controller:

  • Add validation that HelmRelease contains correct valuesFrom configuration
  • Remove CozystackConfigReconciler (no longer needed)
  • Remove TenantHelmReconciler (no longer needed)

Helm charts (40+ files):

  • Add helper templates in cozy-lib for _cluster/_namespace access
  • Replace ConfigMap lookups with .Values._cluster.*
  • Replace Namespace annotation lookups with .Values._namespace.*

Architecture:

Secret cozystack-values (in each namespace)
├── _cluster: YAML with data from ConfigMaps (cozystack, cozystack-branding, cozystack-scheduling)
└── _namespace: YAML with namespace service references (etcd, host, ingress, monitoring, seaweedfs)

HelmRelease
└── spec.valuesFrom:
    ├── Secret/cozystack-values → _namespace → .Values._namespace
    └── Secret/cozystack-values → _cluster → .Values._cluster

Release note

[platform] Replace Helm lookup functions with FluxCD valuesFrom mechanism for configuration propagation

Summary by CodeRabbit

  • New Features

    • Helm releases and namespaces now source centralized cluster/namespace configuration via a new secret (cozystack-values), and many templates read values from chart-provided _cluster/_namespace entries.
  • Bug Fixes

    • API now rejects application specs containing reserved keys prefixed with "_" to prevent invalid configurations.
  • Refactor

    • Two background reconciler controllers were removed from startup, simplifying controller initialization.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Pre-merge checks and finishing touches

✅ 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 clearly summarizes the main architectural change: replacing Helm lookup functions with FluxCD's valuesFrom mechanism for configuration propagation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @kvaps, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors how configuration is managed and propagated within the platform's HelmReleases. By leveraging FluxCD's valuesFrom feature, it moves away from imperative Helm lookup functions and custom reconciliation logic towards a more declarative and streamlined approach. This change centralizes configuration data into a dedicated cozystack-values Secret, which is then dynamically injected into HelmReleases, simplifying the overall architecture and reducing the need for custom controllers.

Highlights

  • Configuration Management Refactor: Replaced direct Helm lookup functions for ConfigMaps and Namespace annotations with FluxCD's valuesFrom mechanism, centralizing configuration propagation through a cozystack-values Secret.
  • Controller Simplification: Removed the CozystackConfigReconciler and TenantHelmReconciler from cozystack-controller, as their functionality is now handled by the valuesFrom mechanism, leading to a cleaner and more efficient control plane.
  • Dynamic Resource Definition Charts: The monolithic cozystack-resource-definitions Helm chart has been split into individual charts for each resource definition (e.g., bootbox-rd, bucket-rd), improving modularity and maintainability.
  • API and Chart Updates: Updated cozystack-api to automatically inject valuesFrom references into HelmReleases and added validation to prevent user-defined values from using reserved keys (starting with _). Over 40 Helm charts were modified to consume configuration via .Values._cluster and .Values._namespace.
  • Centralized Configuration Secret: Introduced the creation of a cozystack-values Secret in platform and tenant namespaces, which aggregates cluster-wide and namespace-specific configuration data for consumption by HelmReleases.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@kvaps kvaps force-pushed the replace-lookup-with-valuesfrom branch from 3844efb to 9fee714 Compare January 2, 2026 19:48
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a significant and well-executed refactoring that replaces Helm lookup functions with the FluxCD valuesFrom mechanism. This greatly improves configuration propagation, making Helm charts cleaner and more declarative. The removal of the now-redundant CozystackConfigReconciler and TenantHelmReconciler controllers, and the splitting of the monolithic cozystack-resource-definitions chart are excellent architectural improvements.

The changes across the numerous Helm charts are consistent and correctly apply the new pattern of accessing configuration from .Values._cluster and .Values._namespace. The corresponding changes in the cozystack-api and cozystack-controller to support this new mechanism are also well-implemented.

I have found one critical issue in the keycloak-configure chart that will likely cause a template rendering error. Please see the detailed comment below.

@kvaps kvaps force-pushed the replace-lookup-with-valuesfrom branch 5 times, most recently from 05f2b51 to b92477e Compare January 2, 2026 20:42
@kvaps
Copy link
Member Author

kvaps commented Jan 2, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
packages/apps/vpn/templates/secret.yaml (1)

62-63: Remove debug code that leaks passwords.

The foo field appears to be debug code that serializes all user passwords to JSON. This exposes sensitive credentials and should be removed before merging.

🔎 Proposed fix
 type: Opaque
-foo: |
-  {{ toJson $passwords }}
 stringData:
packages/system/keycloak-configure/templates/configure-kk.yaml (1)

9-21: Fix incorrect branding key access on line 20.

Line 20 attempts to access $brandingConfig.branding, but .Values._cluster.branding is already the branding map extracted from the cozystack-branding ConfigMap. The map contains specific keys (tenantText, footerText, titleText, logoText, logoSvg, iconSvg), not a nested branding key.

Change {{- $branding = $brandingConfig.branding }} to access an appropriate field from the branding config based on what the Keycloak realm displayName should represent (e.g., titleText or tenantText).

packages/core/platform/templates/apps.yaml (1)

6-7: Duplicate variable assignment.

Line 7 duplicates the assignment on line 6. One of these should be removed.

🔎 Suggested fix
 {{- $host := "example.org" }}
-{{- $host := "example.org" }}
🧹 Nitpick comments (5)
packages/system/dashboard/templates/nginx-config.yaml (1)

1-1: Consider adding defensive checks for missing configuration values.

The template directly accesses .Values._cluster."root-host" without handling cases where the map might be nil or the key might be missing, which could cause template rendering failures during deployment.

🔎 Suggested defensive pattern
-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := index .Values._cluster "root-host" | default "" }}
+{{- if not $host }}
+{{- fail "Required value _cluster.root-host is missing from cozystack-values Secret" }}
+{{- end }}

This provides an explicit error message if the value is missing, making troubleshooting easier.


Note: The YAMLlint syntax error reported by static analysis is a false positive—it doesn't recognize Helm template syntax ({{-).

packages/library/cozy-lib/templates/_cozyconfig.tpl (1)

59-74: Consider returning an empty dict for structural consistency.

The cozy-lib.scheduling and cozy-lib.branding helpers return nothing when the value is unset, which differs from other helpers that return "". Downstream templates using these helpers with | fromYaml may need to handle the empty case explicitly.

🔎 Optional: Return empty dict when unset
 {{- define "cozy-lib.scheduling" -}}
 {{- if .Values._cluster.scheduling }}
 {{- .Values._cluster.scheduling | toYaml }}
+{{- else }}
+{{- dict | toYaml }}
 {{- end }}
 {{- end }}
packages/system/dashboard/templates/configmap.yaml (1)

19-24: Minor: Inconsistent spacing after colons.

Lines 22-24 have extra spaces after the colon compared to lines 19-21. Consider aligning them consistently for readability.

🔎 Suggested fix
-  TITLE_TEXT:  {{ $brandingConfig.titleText  | default $titleText  | quote }}
-  LOGO_TEXT:   {{ $brandingConfig.logoText   | default $logoText   | quote }}
-  CUSTOM_LOGO_SVG:    {{ $brandingConfig.logoSvg    | default $logoSvg    | quote }}
-  ICON_SVG:    {{ $brandingConfig.iconSvg    | default $iconSvg    | quote }}
+  TITLE_TEXT: {{ $brandingConfig.titleText | default $titleText | quote }}
+  LOGO_TEXT: {{ $brandingConfig.logoText | default $logoText | quote }}
+  CUSTOM_LOGO_SVG: {{ $brandingConfig.logoSvg | default $logoSvg | quote }}
+  ICON_SVG: {{ $brandingConfig.iconSvg | default $iconSvg | quote }}
internal/controller/cozystackresourcedefinition_helmreconciler.go (1)

120-135: Order-sensitive comparison may cause unnecessary updates.

valuesFromEqual performs positional comparison. If an existing HelmRelease has the same ValuesReference entries but in a different order, this will trigger an unnecessary update. Consider using an order-independent comparison if order doesn't matter semantically.

🔎 Suggested order-independent comparison
 // valuesFromEqual compares two ValuesReference slices
 func valuesFromEqual(a, b []helmv2.ValuesReference) bool {
 	if len(a) != len(b) {
 		return false
 	}
-	for i := range a {
-		if a[i].Kind != b[i].Kind ||
-			a[i].Name != b[i].Name ||
-			a[i].ValuesKey != b[i].ValuesKey ||
-			a[i].TargetPath != b[i].TargetPath ||
-			a[i].Optional != b[i].Optional {
-			return false
+	// Create a map for order-independent comparison
+	aSet := make(map[string]helmv2.ValuesReference, len(a))
+	for _, ref := range a {
+		key := fmt.Sprintf("%s/%s/%s", ref.Kind, ref.Name, ref.ValuesKey)
+		aSet[key] = ref
+	}
+	for _, ref := range b {
+		key := fmt.Sprintf("%s/%s/%s", ref.Kind, ref.Name, ref.ValuesKey)
+		aRef, exists := aSet[key]
+		if !exists || aRef.TargetPath != ref.TargetPath || aRef.Optional != ref.Optional {
+			return false
 		}
 	}
 	return true
 }
packages/apps/tenant/templates/namespace.yaml (1)

70-88: Secret structure is correct for valuesFrom.

The Secret properly provides _cluster and _namespace as YAML strings that FluxCD can inject via valuesFrom. The reconcile.fluxcd.io/watch: Enabled label ensures HelmReleases reconcile when this Secret changes.

Consider adding a default for _cluster for consistency with _namespace handling at line 10:

   _cluster: |
-    {{- .Values._cluster | toYaml | nindent 4 }}
+    {{- (.Values._cluster | default dict) | toYaml | nindent 4 }}

This prevents a bare null output if _cluster is not provided.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bbeaacc and b92477e.

📒 Files selected for processing (59)
  • cmd/cozystack-controller/main.go
  • internal/controller/cozystackresourcedefinition_helmreconciler.go
  • internal/controller/system_helm_reconciler.go
  • internal/controller/tenant_helm_reconciler.go
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/apps/postgres/templates/db.yaml
  • packages/apps/tenant/templates/etcd.yaml
  • packages/apps/tenant/templates/info.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/virtual-machine/templates/_helpers.tpl
  • packages/apps/vm-instance/templates/_helpers.tpl
  • packages/apps/vpn/templates/secret.yaml
  • packages/core/platform/templates/apps.yaml
  • packages/core/platform/templates/helmreleases.yaml
  • packages/core/platform/templates/namespaces.yaml
  • packages/extra/bootbox/templates/matchbox/ingress.yaml
  • packages/extra/bootbox/templates/matchbox/machines.yaml
  • packages/extra/etcd/templates/etcd-cluster.yaml
  • packages/extra/info/templates/dashboard-resourcemap.yaml
  • packages/extra/info/templates/kubeconfig.yaml
  • packages/extra/ingress/templates/nginx-ingress.yaml
  • packages/extra/monitoring/templates/alerta/alerta-db.yaml
  • packages/extra/monitoring/templates/alerta/alerta.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/extra/seaweedfs/templates/client/cosi-deployment.yaml
  • packages/extra/seaweedfs/templates/ingress.yaml
  • packages/extra/seaweedfs/templates/seaweedfs.yaml
  • packages/library/cozy-lib/templates/_cozyconfig.tpl
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
  • packages/tests/cozy-lib-tests/tests/quota_values.yaml
  • pkg/registry/apps/application/rest.go
💤 Files with no reviewable changes (3)
  • cmd/cozystack-controller/main.go
  • internal/controller/tenant_helm_reconciler.go
  • internal/controller/system_helm_reconciler.go
🧰 Additional context used
📓 Path-based instructions (7)
packages/core/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/core/platform/templates/namespaces.yaml
  • packages/core/platform/templates/helmreleases.yaml
  • packages/core/platform/templates/apps.yaml
**/*.yaml

📄 CodeRabbit inference engine (AGENTS.md)

Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms

Files:

  • packages/core/platform/templates/namespaces.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/extra/info/templates/kubeconfig.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/extra/seaweedfs/templates/seaweedfs.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/tests/cozy-lib-tests/tests/quota_values.yaml
  • packages/core/platform/templates/helmreleases.yaml
  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/extra/ingress/templates/nginx-ingress.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/extra/seaweedfs/templates/client/cosi-deployment.yaml
  • packages/extra/info/templates/dashboard-resourcemap.yaml
  • packages/extra/seaweedfs/templates/ingress.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/apps/postgres/templates/db.yaml
  • packages/apps/tenant/templates/etcd.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/apps/vpn/templates/secret.yaml
  • packages/apps/tenant/templates/info.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/extra/bootbox/templates/matchbox/machines.yaml
  • packages/extra/monitoring/templates/alerta/alerta-db.yaml
  • packages/extra/monitoring/templates/alerta/alerta.yaml
  • packages/extra/etcd/templates/etcd-cluster.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
  • packages/extra/bootbox/templates/matchbox/ingress.yaml
  • packages/core/platform/templates/apps.yaml
packages/apps/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/apps/vm-instance/templates/_helpers.tpl
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/apps/postgres/templates/db.yaml
  • packages/apps/virtual-machine/templates/_helpers.tpl
  • packages/apps/tenant/templates/etcd.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/apps/vpn/templates/secret.yaml
  • packages/apps/tenant/templates/info.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/nats/templates/nats.yaml
packages/system/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
internal/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Follow controller-runtime patterns and kubebuilder style for Go code in internal directory

Files:

  • internal/controller/cozystackresourcedefinition_helmreconciler.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Do NOT manually edit vendor/ directory or auto-generated files (zz_generated.*.go)

Files:

  • internal/controller/cozystackresourcedefinition_helmreconciler.go
  • pkg/registry/apps/application/rest.go
pkg/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Follow controller-runtime patterns and kubebuilder style for Go code in pkg directory

Files:

  • pkg/registry/apps/application/rest.go
🧠 Learnings (4)
📚 Learning: 2025-11-28T21:26:10.771Z
Learnt from: kvaps
Repo: cozystack/cozystack PR: 1671
File: packages/apps/postgres/files/versions.yaml:1-6
Timestamp: 2025-11-28T21:26:10.771Z
Learning: In packages/apps/postgres/files/versions.yaml, the version mappings are sourced from the CloudNativePG container registry (ghcr.io/cloudnative-pg/postgresql), not from PostgreSQL project releases. The versions should reflect what's actually published in the CloudNativePG registry, which is automatically fetched by the hack/update-versions.sh script.

Applied to files:

  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/postgres/templates/db.yaml
📚 Learning: 2025-07-26T18:26:01.447Z
Learnt from: NickVolynkin
Repo: cozystack/cozystack PR: 1216
File: packages/extra/monitoring/README.md:30-31
Timestamp: 2025-07-26T18:26:01.447Z
Learning: The cozyvalues-gen tool has a known issue (https://github.com/cozystack/cozyvalues-gen/issues/10) where it incorrectly places Grafana configuration entries under the wrong documentation sections, specifically placing grafana.resources.requests.* entries in the Metrics storage configuration table instead of the Grafana configuration table.

Applied to files:

  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
📚 Learning: 2025-07-23T09:15:09.658Z
Learnt from: lllamnyp
Repo: cozystack/cozystack PR: 1233
File: packages/system/hetzner-robotlb/charts/robotlb/templates/deployment.yaml:33-35
Timestamp: 2025-07-23T09:15:09.658Z
Learning: The `./charts/robotlb/` directory in the hetzner-robotlb package contains vendored code, and the team generally avoids modifying vendored code to maintain clean separation from upstream dependencies.

Applied to files:

  • packages/extra/seaweedfs/templates/client/cosi-deployment.yaml
📚 Learning: 2025-07-03T05:54:51.264Z
Learnt from: NickVolynkin
Repo: cozystack/cozystack PR: 1120
File: packages/apps/clickhouse/README.md:60-67
Timestamp: 2025-07-03T05:54:51.264Z
Learning: The `cozy-lib.resources.sanitize` function in packages/library/cozy-lib/templates/_resources.tpl supports both standard Kubernetes resource format (with limits:/requests: sections) and flat format (direct resource specifications). The flat format takes priority over nested values. CozyStack apps include cozy-lib as a chart dependency through symlinks in packages/apps/*/charts/cozy-lib directories.

Applied to files:

  • packages/library/cozy-lib/templates/_cozyconfig.tpl
  • packages/extra/etcd/templates/etcd-cluster.yaml
🧬 Code graph analysis (1)
pkg/registry/apps/application/rest.go (1)
pkg/apis/apps/v1alpha1/types.go (1)
  • Application (66-74)
🪛 YAMLlint (1.37.1)
packages/apps/foundationdb/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/cozystack-api/templates/api-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/info/templates/kubeconfig.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak/templates/sts.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/bucket/templates/bucketclaim.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak-configure/templates/configure-kk.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/keycloakclient.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/clickhouse/templates/chkeeper.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/nginx-config.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/tenant/templates/namespace.yaml

[error] 2-2: syntax error: expected '', but found '{'

(syntax)

packages/extra/monitoring/templates/grafana/grafana.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/ingress/templates/nginx-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak/templates/db.yaml

[error] 10-10: syntax error: could not find expected ':'

(syntax)

packages/extra/info/templates/dashboard-resourcemap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/configmap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)


[warning] 22-22: too many spaces after colon

(colons)


[warning] 23-23: too many spaces after colon

(colons)


[warning] 24-24: too many spaces after colon

(colons)

packages/apps/kubernetes/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/cert-manager-issuers/templates/cluster-issuers.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/clickhouse/templates/clickhouse.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/bucket/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/gatekeeper.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/vpn/templates/secret.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/tenant/templates/keycloakgroups.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/nats/templates/nats.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/bootbox/templates/matchbox/machines.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/monitoring/templates/alerta/alerta-db.yaml

[error] 9-9: syntax error: could not find expected ':'

(syntax)

packages/extra/monitoring/templates/alerta/alerta.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/monitoring/templates/grafana/db.yaml

[error] 10-10: syntax error: could not find expected ':'

(syntax)

packages/extra/bootbox/templates/matchbox/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🔇 Additional comments (67)
packages/extra/ingress/templates/nginx-ingress.yaml (3)

1-2: LGTM! Values sourcing migrated correctly.

The migration from ConfigMap lookup to .Values._cluster is implemented correctly with sensible defaults ("tenant-root" and "").


1-1: Static analysis false positive - safely ignore.

YAMLlint reports a syntax error because it doesn't understand Helm template syntax. The {{- delimiter is valid Helm templating and will render correctly.


26-34: Code structure is correct and follows established patterns; no issues found.

The valuesFrom configuration correctly references the cozystack-values Secret with both required keys. This hard dependency is expected and by design—the Secret is created in the platform chart (packages/core/platform/templates/apps.yaml) before tenant charts reconcile. The same pattern is used consistently across other charts like seaweedfs. Since this is a custom chart (not a vendored upstream chart), it can be edited directly.

packages/system/dashboard/templates/keycloakclient.yaml (1)

1-2: This review comment is incorrect. The code is correct as written.

The root-host value is intentionally required without a default. The platform chart explicitly validates its presence in the cozystack ConfigMap with a fail statement before any charts are deployed. The absence of a default in line 1 is correct and consistent with all other templates that use root-host across the codebase (dashboard, keycloak, kubevirt, etc.). The extra-keycloak-redirect-uri-for-dashboard on line 2 appropriately has a default because it is genuinely optional, unlike root-host which is mandatory cluster configuration.

Likely an incorrect or invalid review comment.

packages/system/keycloak/templates/sts.yaml (1)

4-8: Password persistence lookup is intentional; verify it aligns with the system's secret management approach.

This lookup for password persistence across upgrades differs from the configuration migration being addressed in the PR. The pattern is used consistently in other custom templates (keycloak-configure, bucket, dashboard) to manage stateful secrets. Confirm whether the current lookup-based approach for credentials remains the preferred pattern, or if credentials should eventually be managed via external operators or dedicated Secrets referenced through valuesFrom.

packages/apps/tenant/templates/keycloakgroups.yaml (2)

2-53: LGTM: Proper conditional gating for KeycloakRealmGroup resources.

The double-conditional pattern correctly gates resource creation behind both the feature flag (oidc-enabled) and API availability check. This ensures the resources are only created when OIDC is enabled and the KeycloakRealmGroup CRD is installed.


1-1: The valuesFrom configuration is properly set up.

The HelmRelease in packages/core/platform/templates/apps.yaml correctly references the cozystack-values Secret with valuesKey: _cluster and targetPath: _cluster with optional: false. This ensures .Values._cluster is populated at deployment time, making the index .Values._cluster "oidc-enabled" usage on line 1 safe and correct.

packages/extra/etcd/templates/etcd-cluster.yaml (1)

52-69: Pattern is safe and consistent across the codebase.

The truthy check on .Values._cluster.scheduling before using the get function adequately protects against type issues. This pattern is consistently used across 8 different templates (etcd, grafana, alerta, keycloak, ferretdb, kubernetes, postgres) and relies on Flux's validated data parsing from the cozystack-values Secret. The fallback logic provides safe defaults when constraints are not present, making this implementation robust.

packages/system/cert-manager-issuers/templates/cluster-issuers.yaml (1)

1-1: Migration from ConfigMap lookup to values-based configuration is correct.

The change properly replaces the ConfigMap lookup with .Values._cluster.clusterissuer access and an appropriate "http01" default. The HelmRelease for cert-manager-issuers is automatically generated with the correct valuesFrom configuration (referencing Secret/cozystack-values for the _cluster namespace values), as shown in the platform's helmreleases.yaml template. This aligns with the PR's objective to use FluxCD valuesFrom mechanism.

packages/extra/bootbox/templates/matchbox/machines.yaml (2)

40-40: LGTM: Boot URL construction with user override capability.

The dual-source pattern allows users to override the host via .Values.host while falling back to the namespace default (.Values._namespace.host). This provides good flexibility for customization while maintaining sensible defaults from the new valuesFrom architecture.


1-1: No action required—.Values._namespace.host is properly guaranteed to be populated.

Bootbox deploys to the tenant-root namespace, where the cozystack-values Secret is created with _namespace.host set to the cluster's root hostname (determined from cluster config or tenant-root HelmRelease values, with fallback to "example.org"). The dual-source pattern on line 39 ($.Values.host | default $host) correctly allows user override while falling back to the namespace-provided value.

The YAMLlint syntax error is a false positive—Helm template syntax is valid.

packages/apps/clickhouse/templates/clickhouse.yaml (1)

1-1: LGTM! Clean migration to values-based configuration.

The replacement of ConfigMap lookup with .Values._cluster "cluster-domain" aligns with the PR's architecture of using FluxCD valuesFrom for configuration propagation. The default value is preserved.

packages/apps/vm-instance/templates/_helpers.tpl (1)

77-78: LGTM! Consistent with the valuesFrom pattern.

The migration from ConfigMap lookup to .Values._cluster.scheduling follows the PR's architectural goal. The Windows VM affinity logic remains intact.

packages/extra/seaweedfs/templates/ingress.yaml (1)

1-2: LGTM! Values-based configuration properly implemented.

Replacing Namespace annotation lookups with .Values._namespace.ingress and .Values._namespace.host is consistent with the PR's approach to eliminate runtime lookups in favor of value propagation.

packages/extra/monitoring/templates/alerta/alerta.yaml (1)

1-3: LGTM! Configuration migration correctly implemented.

The transition from ConfigMap/Namespace lookups to .Values._cluster and .Values._namespace follows the PR's pattern. Default values are preserved, and the variables are used consistently throughout the template.

packages/apps/kubernetes/templates/ingress.yaml (1)

1-1: LGTM! Clean refactor to values-based ingress configuration.

Replacing the Namespace annotation lookup with .Values._namespace.ingress is consistent with the PR's architecture to propagate configuration via FluxCD valuesFrom rather than runtime lookups.

packages/apps/postgres/templates/db.yaml (1)

49-57: LGTM: Proper nil-safety for optional scheduling configuration.

The nested conditional checks ensure safe access to optional topology spread constraints. The pattern correctly handles cases where .Values._cluster.scheduling or globalAppTopologySpreadConstraints may be absent, preventing template rendering failures.

packages/extra/monitoring/templates/grafana/db.yaml (1)

9-17: LGTM: Proper nil-safety for optional scheduling configuration.

The implementation correctly mirrors the pattern in postgres/templates/db.yaml with nested conditionals ensuring safe access to optional topology spread constraints.

Note: The YAMLlint syntax error on line 10 is a false positive—the tool doesn't recognize Helm templating directives.

packages/system/bucket/templates/ingress.yaml (1)

1-3: HelmRelease properly configured with valuesFrom—verify cozystack-values Secret contains required _namespace values.

The template depends on .Values._namespace.host and .Values._namespace.ingress without fallback defaults. The HelmRelease correctly pulls these from the cozystack-values Secret via valuesFrom (lines 24-32 in packages/apps/bucket/templates/helmrelease.yaml), but deployment will fail if the Secret is missing or lacks the _namespace key with host and ingress fields. Ensure the Secret populates these values when provisioning tenant environments.

packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml (1)

1-3: Verify that .Values._cluster.root-host is populated.

The host variable (line 1) has no default value and is required if the Ingress is rendered (when vm-exportproxy is in expose-services). If .Values._cluster is missing root-host, the template will fail at line 17.

The conditional rendering at line 5 provides some protection, but it's still important to ensure the Secret is properly configured. Use the same verification as the keycloak ingress review above to confirm that _cluster.root-host is present in the cozystack-values Secret.

packages/apps/ferretdb/templates/postgres.yaml (1)

53-61: LGTM! Proper defensive nil checking.

The topology spread constraints logic correctly implements the migration pattern with multiple levels of safety:

  1. Line 53 checks if .Values._cluster.scheduling exists
  2. Line 54 uses get which safely returns nil for missing keys
  3. Line 55 validates that constraints data is present

This ensures the template won't fail even if the Secret is missing scheduling configuration.

packages/system/keycloak/templates/ingress.yaml (1)

1-3: Upstream validation ensures .Values._cluster.root-host is populated.

The host variable (line 1) has no default value, but this is by design—the platform bundles (paas-hosted.yaml and paas-full.yaml) validate that root-host exists in the cozystack ConfigMap before rendering any system charts. The cozystack-values Secret is created from that ConfigMap, ensuring the required keys are present. All system templates in the packages follow this same pattern of relying on upstream platform-level validation.

packages/apps/virtual-machine/templates/_helpers.tpl (1)

77-78: Verify that .Values._cluster.scheduling is populated by valuesFrom — Confirmed.

The migration from ConfigMap lookup to Helm values is correctly implemented with defensive nil checking. The cozystack-values Secret includes the _cluster.scheduling data sourced from the cozystack-scheduling ConfigMap, and HelmRelease configurations properly reference this Secret via valuesFrom with valuesKey: _cluster and targetPath: _cluster. The code safely handles optional keys using the get() function.

packages/system/cozystack-api/templates/api-ingress.yaml (1)

1-3: LGTM!

The migration from ConfigMap lookup to .Values._cluster access is correctly implemented with appropriate defaults. The static analysis YAML syntax error on line 1 is a false positive—Helm template directives ({{-) are valid syntax for .tpl files processed by Helm.

packages/extra/bootbox/templates/matchbox/ingress.yaml (1)

1-3: LGTM with a minor consideration.

The migration to .Values._cluster and .Values._namespace is correctly implemented. Note that if .Values._namespace is not populated (e.g., the Secret is missing or valuesFrom fails), accessing .ingress and .host will return nil. This is acceptable since the HelmRelease controller validates valuesFrom configuration, and missing secrets would surface as reconciliation errors before template rendering.

packages/extra/seaweedfs/templates/seaweedfs.yaml (2)

37-38: LGTM!

The migration from Namespace annotation lookups to .Values._namespace.ingress and .Values._namespace.host is consistent with the PR's migration pattern.


62-70: LGTM!

The valuesFrom block correctly references the cozystack-values Secret for both _cluster and _namespace data. This follows the standardized pattern established across the PR for injecting configuration into HelmReleases.

packages/extra/seaweedfs/templates/client/cosi-deployment.yaml (1)

1-2: LGTM!

The migration to .Values._namespace.host is consistent with the PR pattern. Since this template renders a Deployment (not a HelmRelease), ensure that the parent chart's values.yaml or the HelmRelease deploying this chart includes the valuesFrom configuration to populate _namespace.

packages/library/cozy-lib/templates/_cozyconfig.tpl (3)

10-52: LGTM!

The cluster-wide configuration helpers are well-documented and provide consistent access patterns with sensible defaults. Using index for hyphenated keys (e.g., "root-host") is the correct approach in Helm templates.


85-119: LGTM!

The namespace-specific helpers follow the same consistent pattern as the cluster-wide helpers, with appropriate defaults for missing values.


121-129: LGTM!

The legacy helper is appropriately maintained for backward compatibility during migration. The deprecation note in the comment is helpful for future cleanup.

packages/apps/tenant/templates/info.yaml (1)

33-41: LGTM!

The valuesFrom configuration follows the standardized pattern for injecting _cluster and _namespace values from the cozystack-values Secret. This is consistent with other tenant templates and HelmReleases across the PR.

packages/tests/cozy-lib-tests/tests/quota_values.yaml (1)

6-8: LGTM!

Adding empty _cluster and _namespace mappings ensures the cozy-lib helper tests can execute without nil-reference errors when accessing .Values._cluster or .Values._namespace.

packages/apps/bucket/templates/helmrelease.yaml (1)

24-32: LGTM: Consistent valuesFrom implementation.

The valuesFrom block follows the same correct pattern as other templates, sourcing _cluster and _namespace from Secret cozystack-values.

packages/apps/tenant/templates/ingress.yaml (1)

34-42: LGTM: Consistent valuesFrom implementation.

The valuesFrom configuration correctly follows the established pattern.

packages/apps/tenant/templates/seaweedfs.yaml (1)

34-42: LGTM: Consistent valuesFrom implementation.

The valuesFrom configuration is correctly implemented.

packages/apps/tenant/templates/etcd.yaml (1)

34-42: valuesFrom configuration correctly implemented.

The valuesFrom block correctly references the cozystack-values Secret from packages/apps/tenant/templates/namespace.yaml, which defines both required keys (_cluster and _namespace) for each tenant namespace. The Helm Chart umbrella pattern with vendored charts (cozy-lib symlink) is properly followed, and the external chart reference to cozystack-extra is appropriately configured.

Ensure that the Secret cozystack-values exists in the tenant namespace and contains the required _cluster and _namespace keys before this HelmRelease reconciles.

packages/apps/foundationdb/templates/cluster.yaml (1)

1-1: Verify HelmRelease valuesFrom configuration for foundationdb.

The template correctly reads cluster-domain from .Values._cluster with a fallback to "cozy.local". However, the CozystackResourceDefinition for foundationdb does not explicitly show valuesFrom injection of the _cluster secret (unlike direct HelmRelease templates used by other apps). Confirm that the resource definition reconciler automatically injects valuesFrom to populate _cluster from Secret cozystack-values.

packages/extra/info/templates/dashboard-resourcemap.yaml (1)

1-1: LGTM!

The migration from ConfigMap lookup to .Values._cluster["oidc-enabled"] is correct and aligns with the PR's objective to replace lookups with valuesFrom-driven configuration. The YAMLlint error is a false positive—Helm template syntax is valid here.

packages/core/platform/templates/helmreleases.yaml (1)

86-94: LGTM!

The valuesFrom configuration correctly references the cozystack-values Secret with separate entries for _cluster and _namespace. This aligns with the FluxCD valuesFrom specification and the PR's migration pattern.

packages/system/dashboard/templates/gatekeeper.yaml (1)

1-2: LGTM!

The migration from ConfigMap lookup to .Values._cluster["root-host"] and .Values._cluster["oidc-enabled"] is correct. The YAMLlint syntax error is a false positive for Helm templates.

packages/extra/monitoring/templates/alerta/alerta-db.yaml (1)

8-16: LGTM!

The defensive nil-check pattern with nested conditionals is correct—first verifying .Values._cluster.scheduling exists before accessing globalAppTopologySpreadConstraints. The YAMLlint error is a false positive for Helm template syntax.

packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml (1)

1-1: LGTM!

The migration from Namespace annotation lookup to .Values._namespace.monitoring is correct. The YAMLlint syntax error is a false positive.

Consider verifying that the cozystack-values Secret always populates the monitoring key under _namespace for namespaces where this HelmRelease is deployed, to avoid empty $targetTenant values in service URLs.

packages/apps/tenant/templates/monitoring.yaml (1)

34-42: LGTM!

The valuesFrom configuration correctly injects _cluster and _namespace from the cozystack-values Secret, consistent with the pattern used across other HelmRelease templates in this PR.

packages/apps/vpn/templates/secret.yaml (1)

1-1: LGTM!

The migration from Namespace annotation lookup to .Values._namespace.host is correct and consistent with the PR pattern. The YAMLlint syntax error is a false positive.

packages/core/platform/templates/namespaces.yaml (2)

2-3: LGTM: ConfigMap lookups appropriate for platform chart.

The addition of branding and scheduling ConfigMap lookups is correct here. The platform chart aggregates configuration from multiple ConfigMaps into the cozystack-values Secret, which downstream charts consume via valuesFrom.


42-62: LGTM: Secret structure correctly aggregates cluster configuration.

The cozystack-values Secret properly aggregates configuration from multiple ConfigMaps into a single _cluster key. The indentation levels ensure branding and scheduling are merged at the correct level with the base configuration data.

The Flux watch label ensures the Secret is monitored for changes.

packages/apps/clickhouse/templates/chkeeper.yaml (1)

1-1: LGTM: Clean migration with appropriate default.

The migration from ConfigMap lookup to .Values._cluster with a sensible default value of "cozy.local" is correct and consistent with the PR's objective.

packages/system/keycloak/templates/db.yaml (1)

9-17: LGTM: Correct migration of scheduling constraints.

The migration from ConfigMap-based constraint retrieval to .Values._cluster.scheduling is correct. The get function safely extracts the globalAppTopologySpreadConstraints key from the scheduling map.

The static analysis error on line 10 is a false positive—yamllint doesn't recognize Helm template syntax. The template logic is sound: it checks for the existence of .Values._cluster.scheduling before attempting to extract constraints, preventing nil reference errors.

packages/system/dashboard/templates/ingress.yaml (1)

1-4: No action needed. The root-host value is guaranteed to be present in the cozystack ConfigMap by upstream platform validation. The platform bundles explicitly fail deployment with the error "ERROR need root-host in cozystack ConfigMap" if this value is missing. Multiple other system packages follow the same pattern without local defaults, which is consistent with the Helm Chart umbrella pattern used in this codebase where values are injected and validated at the platform level, not locally. Adding a default value would be unnecessary and inconsistent with the established architectural pattern.

packages/system/dashboard/templates/configmap.yaml (1)

1-1: LGTM on the migration to values-based branding config.

The pattern correctly sources branding from .Values._cluster.branding with a fallback to an empty dict, aligning with the PR's objective to replace ConfigMap lookups with valuesFrom-injected values.

packages/extra/info/templates/kubeconfig.yaml (1)

1-9: LGTM on the migration to values-based configuration.

The template correctly migrates:

  • Host resolution from namespace values with fallback to cluster config
  • API server and management kubeconfig endpoints from cluster values
  • The conditional override logic for managementKubeconfigEndpoint is preserved
internal/controller/cozystackresourcedefinition_helmreconciler.go (2)

100-118: LGTM on expectedValuesFrom helper.

The function correctly defines the expected ValuesFrom configuration that aligns with the PR's architecture: sourcing _namespace and _cluster from the cozystack-values Secret.


194-200: LGTM on valuesFrom synchronization logic.

The logic correctly checks and updates the HelmRelease's ValuesFrom to match the expected configuration, ensuring consistency across all managed HelmReleases.

packages/apps/kubernetes/templates/cluster.yaml (2)

1-3: LGTM on namespace values extraction.

The template correctly sources etcd, ingress, and host from .Values._namespace, aligning with the PR's valuesFrom-based configuration approach.


33-41: No issue found with .Values context inside the define block.

The concern about context is unfounded. At line 251, $context := deepCopy $ copies the entire root context including .Values at the root template level. This context is then passed to the kubevirtmachinetemplate define block at line 254. Inside the define block, .Values._cluster.scheduling correctly accesses the root values through the passed context.

Likely an incorrect or invalid review comment.

packages/apps/nats/templates/nats.yaml (2)

55-63: LGTM on valuesFrom configuration.

The HelmRelease correctly references the cozystack-values Secret to inject _cluster and _namespace values, following the consistent pattern established across the PR.


1-1: LGTM on cluster-domain sourcing.

The template correctly sources cluster-domain from .Values._cluster with a sensible default of cozy.local.

pkg/registry/apps/application/rest.go (4)

885-900: Only top-level keys are validated.

validateNoInternalKeys only checks top-level keys in the JSON object. If users provide nested structures like {"foo": {"_internal": "value"}}, this would pass validation. Is this intentional, or should validation be recursive?

If recursive validation is needed:

🔎 Recursive validation approach
 // validateNoInternalKeys checks that values don't contain keys starting with "_"
 func validateNoInternalKeys(values *apiextv1.JSON) error {
 	if values == nil || len(values.Raw) == 0 {
 		return nil
 	}
 	var data map[string]interface{}
 	if err := json.Unmarshal(values.Raw, &data); err != nil {
 		return err
 	}
-	for key := range data {
-		if strings.HasPrefix(key, "_") {
-			return fmt.Errorf("values key %q is reserved (keys starting with '_' are not allowed)", key)
-		}
-	}
-	return nil
+	return validateNoInternalKeysRecursive(data, "")
+}
+
+func validateNoInternalKeysRecursive(data map[string]interface{}, path string) error {
+	for key, value := range data {
+		fullPath := key
+		if path != "" {
+			fullPath = path + "." + key
+		}
+		if strings.HasPrefix(key, "_") {
+			return fmt.Errorf("values key %q is reserved (keys starting with '_' are not allowed)", fullPath)
+		}
+		if nested, ok := value.(map[string]interface{}); ok {
+			if err := validateNoInternalKeysRecursive(nested, fullPath); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
 }

864-883: Filtering also only applies to top-level keys.

Similar to validation, filterInternalKeys only removes top-level keys starting with _. Nested internal keys would still be included in the response. Ensure this aligns with the intended security model.


989-1004: LGTM on ValuesFrom injection.

The HelmRelease conversion correctly adds ValuesFrom references for both _namespace and _cluster from the cozystack-values Secret, ensuring applications receive the required configuration.


151-154: LGTM on input validation.

Validation correctly rejects user-provided values containing reserved keys (starting with _) during both Create and Update operations, returning appropriate BadRequest errors.

Also applies to: 450-453

packages/core/platform/templates/apps.yaml (2)

36-61: LGTM on cozystack-values Secret structure.

The Secret correctly aggregates cluster-wide configuration (including branding and scheduling) into _cluster and namespace-specific service references into _namespace, providing a centralized configuration source for HelmReleases.


89-99: LGTM on valuesFrom configuration for tenant-root.

The HelmRelease correctly references the cozystack-values Secret with both _namespace and _cluster keys mapped to their respective target paths, enabling the tenant chart to access the injected configuration.

packages/apps/tenant/templates/namespace.yaml (3)

1-5: LGTM - Namespace UID lookup is appropriate here.

This lookup for the existing namespace UID is intentional and different from the ConfigMap/annotation lookups being removed in this PR. The UID is required for ownerReferences and cannot be pre-computed via values.

The YAMLlint syntax error at line 2 is a false positive — this is a Helm template file, and {{- is valid Go template syntax.


8-40: Clean value computation logic.

The pattern for computing service references is consistent and handles inheritance correctly:

  • Services default to parent namespace values
  • When a service is enabled in .Values, it's overridden to use the tenant name
  • Host computation properly handles both explicit and derived (subdomain) cases

42-69: Network policy labels correctly migrated to computed values.

The namespace labels now use the computed service references ($etcd, $ingress, $monitoring, $seaweedfs, $computedHost) instead of reading from namespace annotations. This aligns with the PR's objective of replacing runtime lookups with pre-computed values.

@@ -1,5 +1,4 @@
{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }}
{{- $seaweedfs := index $myNS.metadata.annotations "namespace.cozystack.io/seaweedfs" }}
{{- $seaweedfs := .Values._namespace.seaweedfs }}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add required validation for seaweedfs namespace value.

.Values._namespace.seaweedfs is used without validation or a default. If this value is missing from the cozystack-values Secret, the BucketClaim and BucketAccess resources will have empty class names, causing failures.

🔎 Proposed fix to validate required value
-{{- $seaweedfs := .Values._namespace.seaweedfs }}
+{{- $seaweedfs := .Values._namespace.seaweedfs | required ".Values._namespace.seaweedfs is required for bucket storage configuration" }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $seaweedfs := .Values._namespace.seaweedfs }}
{{- $seaweedfs := .Values._namespace.seaweedfs | required ".Values._namespace.seaweedfs is required for bucket storage configuration" }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
In packages/apps/bucket/templates/bucketclaim.yaml around lines 1 to 1, the
template reads .Values._namespace.seaweedfs without validation so an absent
value produces empty class names; update the template to require or default this
value (use the Helm required function like required "seaweedfs namespace is
required" .Values._namespace.seaweedfs or provide a sane default via default
"seaweedfs" .Values._namespace.seaweedfs) and ensure any downstream usage
references the validated/local variable; this will make Helm fail fast with a
clear error when the value is missing or supply a fallback class name to prevent
empty class names in BucketClaim and BucketAccess.

Comment on lines +2 to +3
{{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}
{{- $targetTenant := .Values._namespace.monitoring }}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add nil-safety for required monitoring namespace value.

While cluster-domain has a sensible default, .Values._namespace.monitoring is accessed without nil-checking or a fallback. Line 17 constructs the Prometheus address using $targetTenant, so a missing value will produce an invalid URL (e.g., http://vmselect-shortterm..svc.cozy.local:8481).

🔎 Proposed fix to add validation or default
 {{- define "cozystack.defaultVPAValues" -}}
 {{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}
-{{- $targetTenant := .Values._namespace.monitoring }}
+{{- $targetTenant := .Values._namespace.monitoring | required ".Values._namespace.monitoring is required for VPA Prometheus configuration" }}
 vpaForVPA: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}
{{- $targetTenant := .Values._namespace.monitoring }}
{{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}
{{- $targetTenant := .Values._namespace.monitoring | required ".Values._namespace.monitoring is required for VPA Prometheus configuration" }}
🤖 Prompt for AI Agents
In packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
around lines 2–3, .Values._namespace.monitoring is used without nil-safety which
can produce invalid service addresses; update the template to guard this value
by applying a default or validation (e.g., use the Helm default pipeline to set
$targetTenant := (.Values._namespace.monitoring | default "monitoring") or
explicitly error when missing), then use $targetTenant in the Prometheus address
construction so a sensible fallback or a clear failure prevents malformed URLs.

Comment on lines +1 to +2
{{- $host := index .Values._cluster "root-host" }}
{{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add a default value for root-host to prevent invalid configuration.

The migration from ConfigMap lookup to .Values._cluster access aligns with the PR objectives. However, root-host lacks a default value, while cluster-domain has one. If root-host is not provided, line 123 will generate an invalid KC_HOSTNAME like https://keycloak. (note the trailing dot), which could cause Keycloak to fail at startup.

🔎 Proposed fix
-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := (index .Values._cluster "root-host") | default "cozy.local" }}
 {{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}

Or validate that the value exists:

+{{- if not (index .Values._cluster "root-host") }}
+{{- fail "root-host must be set in cluster configuration" }}
+{{- end }}
 {{- $host := index .Values._cluster "root-host" }}
 {{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
In packages/system/keycloak/templates/sts.yaml around lines 1-2,
.Values._cluster "root-host" has no default which can produce an invalid
KC_HOSTNAME (e.g. "https://keycloak."); fix by providing a safe default or
validating presence: update the template to use the default function for
root-host (for example defaulting to "keycloak" or another sensible hostname) so
KC_HOSTNAME is well-formed when root-host is omitted, or add a
conditional/validation that fails rendering with a clear error when root-host is
missing.

@kvaps kvaps force-pushed the replace-lookup-with-valuesfrom branch 4 times, most recently from 932327e to 2e79023 Compare January 4, 2026 10:09
@kvaps kvaps marked this pull request as ready for review January 4, 2026 12:52
@kvaps kvaps requested review from lllamnyp and nbykov0 as code owners January 4, 2026 12:52
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. enhancement New feature or request labels Jan 4, 2026
Copy link
Contributor

@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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/apps/clickhouse/templates/clickhouse.yaml (1)

93-104: Critical: Inconsistent cluster domain reference - incomplete migration.

Line 99 references .Values.clusterDomain (old-style), which conflicts with the migration to .Values._cluster "cluster-domain" at Line 1. This creates an inconsistency where the $clusterDomain variable is overridden with a potentially undefined or stale value, breaking the ClickHouse Keeper node configuration.

🔎 Proposed fix
     zookeeper:
       nodes:
         {{- $replicas := int .Values.clickhouseKeeper.replicas }}
         {{- $release := .Release.Name }}
         {{- $namespace := .Release.Namespace }}
-        {{- $clusterDomain := .Values.clusterDomain }}
         {{- range $i := until $replicas }}
         - host: "chk-{{ $release }}-keeper-cluster1-0-{{ $i }}.{{ $namespace }}.svc.{{ $clusterDomain }}"
           port: 2181
         {{- end }}

The $clusterDomain variable from Line 1 should be used directly without reassignment.

♻️ Duplicate comments (4)
packages/apps/bucket/templates/bucketclaim.yaml (1)

1-1: Validation still needed for seaweedfs namespace value.

This issue was previously identified: .Values._namespace.seaweedfs requires validation or a default to prevent empty class names in BucketClaim and BucketAccess resources.

packages/system/keycloak/templates/sts.yaml (1)

1-2: The missing default for root-host remains unaddressed.

This issue was previously identified: without a default value for root-host, line 123 will generate an invalid KC_HOSTNAME like https://keycloak. (note the trailing dot), which could cause Keycloak to fail at startup.

Please add a default value or validation as suggested in the previous review.

packages/extra/monitoring/templates/grafana/grafana.yaml (1)

2-3: Add defaults for _namespace.ingress and _namespace.host to prevent template failures.

Lines 2-3 access .Values._namespace.ingress and .Values._namespace.host without defaults. If the cozystack-values Secret does not populate the _namespace section with these keys, template rendering will fail at line 76 where $ingress is used directly in the ingress class annotation.

While line 82 includes a fallback pattern (.Values.host | default $host), the assignment of $host itself on line 3 should include a fallback to ensure robustness.

🔎 Proposed fix
-{{- $ingress := .Values._namespace.ingress }}
-{{- $host := .Values._namespace.host }}
+{{- $ingress := .Values._namespace.ingress | default "nginx" }}
+{{- $host := .Values._namespace.host | default "" }}
packages/core/platform/templates/apps.yaml (1)

61-68: Missing nil checks for ConfigMap data access.

Same issue as in namespaces.yaml - accessing .data on potentially nil ConfigMaps. This was flagged in a previous review.

🧹 Nitpick comments (3)
packages/apps/kubernetes/templates/ingress.yaml (1)

1-1: Consider adding validation for ingress value.

.Values._namespace.ingress is used without validation. If this value is missing from the cozystack-values Secret, the Ingress resource will have an empty ingressClassName (line 18), which may cause issues.

🔎 Proposed fix to add validation
-{{- $ingress := .Values._namespace.ingress }}
+{{- $ingress := .Values._namespace.ingress | required ".Values._namespace.ingress is required for Proxied ingress configuration" }}
packages/system/bucket/templates/ingress.yaml (1)

1-2: Consider adding validation for required namespace values.

.Values._namespace.host and .Values._namespace.ingress are used without validation. Missing values would result in empty hostname (lines 24, 27) and empty ingressClassName (line 21), causing the Ingress resource to fail.

🔎 Proposed fix to add validation
-{{- $host := .Values._namespace.host }}
-{{- $ingress := .Values._namespace.ingress }}
+{{- $host := .Values._namespace.host | required ".Values._namespace.host is required for ingress configuration" }}
+{{- $ingress := .Values._namespace.ingress | required ".Values._namespace.ingress is required for ingress configuration" }}
 {{- $issuerType := (index .Values._cluster "clusterissuer") | default "http01" }}
packages/core/platform/templates/namespaces.yaml (1)

2-3: Consider adding nil checks for optional ConfigMap lookups.

If cozystack-branding or cozystack-scheduling ConfigMaps don't exist, accessing .data on a nil object (lines 68-74) may cause template errors. While {{- with ... }} handles nil/empty .data gracefully, the issue is that $cozystackBranding.data or $cozystackScheduling.data attempts to access .data on a potentially nil object.

🔎 Suggested fix
-    {{- with $cozystackBranding.data }}
+    {{- if $cozystackBranding }}
+    {{- with $cozystackBranding.data }}
     branding:
       {{- . | toYaml | nindent 8 }}
     {{- end }}
-    {{- with $cozystackScheduling.data }}
+    {{- end }}
+    {{- if $cozystackScheduling }}
+    {{- with $cozystackScheduling.data }}
     scheduling:
       {{- . | toYaml | nindent 8 }}
     {{- end }}
+    {{- end }}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b92477e and 2e79023.

📒 Files selected for processing (59)
  • cmd/cozystack-controller/main.go
  • internal/controller/cozystackresourcedefinition_helmreconciler.go
  • internal/controller/system_helm_reconciler.go
  • internal/controller/tenant_helm_reconciler.go
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/apps/postgres/templates/db.yaml
  • packages/apps/tenant/templates/etcd.yaml
  • packages/apps/tenant/templates/info.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/virtual-machine/templates/_helpers.tpl
  • packages/apps/vm-instance/templates/_helpers.tpl
  • packages/apps/vpn/templates/secret.yaml
  • packages/core/platform/templates/apps.yaml
  • packages/core/platform/templates/helmreleases.yaml
  • packages/core/platform/templates/namespaces.yaml
  • packages/extra/bootbox/templates/matchbox/ingress.yaml
  • packages/extra/bootbox/templates/matchbox/machines.yaml
  • packages/extra/etcd/templates/etcd-cluster.yaml
  • packages/extra/info/templates/dashboard-resourcemap.yaml
  • packages/extra/info/templates/kubeconfig.yaml
  • packages/extra/ingress/templates/nginx-ingress.yaml
  • packages/extra/monitoring/templates/alerta/alerta-db.yaml
  • packages/extra/monitoring/templates/alerta/alerta.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/extra/seaweedfs/templates/client/cosi-deployment.yaml
  • packages/extra/seaweedfs/templates/ingress.yaml
  • packages/extra/seaweedfs/templates/seaweedfs.yaml
  • packages/library/cozy-lib/templates/_cozyconfig.tpl
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
  • packages/tests/cozy-lib-tests/tests/quota_values.yaml
  • pkg/registry/apps/application/rest.go
💤 Files with no reviewable changes (3)
  • cmd/cozystack-controller/main.go
  • internal/controller/system_helm_reconciler.go
  • internal/controller/tenant_helm_reconciler.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • packages/core/platform/templates/helmreleases.yaml
  • packages/tests/cozy-lib-tests/tests/quota_values.yaml
  • packages/apps/virtual-machine/templates/_helpers.tpl
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/tenant/templates/info.yaml
  • packages/library/cozy-lib/templates/_cozyconfig.tpl
  • packages/apps/tenant/templates/etcd.yaml
  • packages/extra/seaweedfs/templates/client/cosi-deployment.yaml
  • packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
🧰 Additional context used
📓 Path-based instructions (7)
**/*.yaml

📄 CodeRabbit inference engine (AGENTS.md)

Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms

Files:

  • packages/extra/etcd/templates/etcd-cluster.yaml
  • packages/apps/postgres/templates/db.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/extra/bootbox/templates/matchbox/ingress.yaml
  • packages/extra/info/templates/dashboard-resourcemap.yaml
  • packages/core/platform/templates/apps.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/extra/info/templates/kubeconfig.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/system/bucket/templates/ingress.yaml
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/extra/seaweedfs/templates/seaweedfs.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/core/platform/templates/namespaces.yaml
  • packages/extra/bootbox/templates/matchbox/machines.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/vpn/templates/secret.yaml
  • packages/extra/ingress/templates/nginx-ingress.yaml
  • packages/extra/monitoring/templates/alerta/alerta-db.yaml
  • packages/extra/monitoring/templates/alerta/alerta.yaml
  • packages/extra/seaweedfs/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
packages/apps/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/apps/postgres/templates/db.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/apps/vm-instance/templates/_helpers.tpl
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/vpn/templates/secret.yaml
pkg/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Follow controller-runtime patterns and kubebuilder style for Go code in pkg directory

Files:

  • pkg/registry/apps/application/rest.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Do NOT manually edit vendor/ directory or auto-generated files (zz_generated.*.go)

Files:

  • pkg/registry/apps/application/rest.go
  • internal/controller/cozystackresourcedefinition_helmreconciler.go
packages/core/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/core/platform/templates/apps.yaml
  • packages/core/platform/templates/namespaces.yaml
packages/system/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/system/keycloak/templates/sts.yaml
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
internal/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Follow controller-runtime patterns and kubebuilder style for Go code in internal directory

Files:

  • internal/controller/cozystackresourcedefinition_helmreconciler.go
🧠 Learnings (3)
📚 Learning: 2025-07-03T05:54:51.264Z
Learnt from: NickVolynkin
Repo: cozystack/cozystack PR: 1120
File: packages/apps/clickhouse/README.md:60-67
Timestamp: 2025-07-03T05:54:51.264Z
Learning: The `cozy-lib.resources.sanitize` function in packages/library/cozy-lib/templates/_resources.tpl supports both standard Kubernetes resource format (with limits:/requests: sections) and flat format (direct resource specifications). The flat format takes priority over nested values. CozyStack apps include cozy-lib as a chart dependency through symlinks in packages/apps/*/charts/cozy-lib directories.

Applied to files:

  • packages/extra/etcd/templates/etcd-cluster.yaml
📚 Learning: 2025-07-26T18:26:01.447Z
Learnt from: NickVolynkin
Repo: cozystack/cozystack PR: 1216
File: packages/extra/monitoring/README.md:30-31
Timestamp: 2025-07-26T18:26:01.447Z
Learning: The cozyvalues-gen tool has a known issue (https://github.com/cozystack/cozyvalues-gen/issues/10) where it incorrectly places Grafana configuration entries under the wrong documentation sections, specifically placing grafana.resources.requests.* entries in the Metrics storage configuration table instead of the Grafana configuration table.

Applied to files:

  • packages/extra/monitoring/templates/grafana/db.yaml
  • packages/extra/monitoring/templates/grafana/grafana.yaml
📚 Learning: 2025-07-11T06:28:13.696Z
Learnt from: lllamnyp
Repo: cozystack/cozystack PR: 1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the `{{-` directive chomps all leading whitespace including newlines back to the previous content, so `{{- toYaml .Values.something | nindent 2 }}` will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., `rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}`).

Applied to files:

  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
🧬 Code graph analysis (1)
pkg/registry/apps/application/rest.go (2)
pkg/apis/apps/v1alpha1/types.go (1)
  • Application (66-74)
pkg/generated/applyconfiguration/apps/v1alpha1/application.go (1)
  • Application (39-46)
🪛 YAMLlint (1.37.1)
packages/extra/monitoring/templates/grafana/db.yaml

[error] 10-10: syntax error: could not find expected ':'

(syntax)

packages/extra/monitoring/templates/grafana/grafana.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/bootbox/templates/matchbox/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/info/templates/dashboard-resourcemap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/info/templates/kubeconfig.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak/templates/sts.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/bucket/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/bucket/templates/bucketclaim.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/nats/templates/nats.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/bootbox/templates/matchbox/machines.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/gatekeeper.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/clickhouse/templates/chkeeper.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/tenant/templates/namespace.yaml

[error] 2-2: syntax error: expected '', but found '{'

(syntax)

packages/apps/clickhouse/templates/clickhouse.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/tenant/templates/keycloakgroups.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/vpn/templates/secret.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/ingress/templates/nginx-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/monitoring/templates/alerta/alerta-db.yaml

[error] 9-9: syntax error: could not find expected ':'

(syntax)

packages/extra/monitoring/templates/alerta/alerta.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/cert-manager-issuers/templates/cluster-issuers.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/cozystack-api/templates/api-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/configmap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)


[warning] 22-22: too many spaces after colon

(colons)


[warning] 23-23: too many spaces after colon

(colons)


[warning] 24-24: too many spaces after colon

(colons)

packages/system/dashboard/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/keycloakclient.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/nginx-config.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak-configure/templates/configure-kk.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak/templates/db.yaml

[error] 10-10: syntax error: could not find expected ':'

(syntax)

packages/system/keycloak/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🔇 Additional comments (55)
packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml (1)

1-3: Migration to .Values._cluster looks correct.

The replacement of ConfigMap lookups with .Values._cluster access aligns with the PR's valuesFrom mechanism. The conditional logic and Ingress configuration are appropriate.

Note: The past review comment about adding a default to line 1 for consistency remains pending.

packages/extra/info/templates/dashboard-resourcemap.yaml (1)

1-1: LGTM! Clean migration from lookup to values-based configuration.

The change correctly replaces the ConfigMap lookup with .Values._cluster["oidc-enabled"], aligning with the PR's architecture where cozystack-values Secrets are injected via valuesFrom. The index function properly accesses the hyphenated key, and the downstream conditional logic remains unchanged.

Note: The YAMLlint syntax error is a false positive—Helm template directives ({{-) are not recognized by standard YAML parsers but are valid in .tpl files.

packages/extra/bootbox/templates/matchbox/machines.yaml (2)

1-1: LGTM! Correctly adopts the new valuesFrom pattern.

The assignment of $host from .Values._namespace.host properly implements the new configuration mechanism, replacing the previous lookup-based approach.


40-40: Fallback pattern is intentional and consistent across bootbox templates.

The .Values.host | default $host pattern appears in three places across the bootbox templates (machines.yaml:40, ingress.yaml:22, ingress.yaml:25), indicating this is a deliberate design—not an oversight. This pattern allows optional override via top-level .Values.host while maintaining .Values._namespace.host as the default, which aligns with maintaining backward compatibility during standardization.

No changes needed.

packages/apps/tenant/templates/keycloakgroups.yaml (1)

1-1: LGTM: Correctly migrated to valuesFrom pattern.

The use of index .Values._cluster "oidc-enabled" correctly accesses the hyphenated key from the values map. This aligns with the PR's objective to replace ConfigMap lookups with valuesFrom references.

The cozystack-values Secret is created by the tenant chart's namespace.yaml template (lines 78-89) with _cluster data populated from parent chart values. Child HelmReleases within the tenant chart (etcd.yaml, info.yaml, ingress.yaml, monitoring.yaml, seaweedfs.yaml) reference this Secret via valuesFrom. The keycloakgroups.yaml template accesses .Values._cluster directly as part of the tenant chart itself, which is consistent with how other apps in packages/apps/ handle this pattern.

packages/extra/info/templates/kubeconfig.yaml (2)

1-1: LGTM! Host configuration successfully migrated to Helm values.

The migration from ConfigMap lookup to .Values._namespace.host with a fallback to .Values._cluster "root-host" aligns perfectly with the PR's objective of replacing lookup functions with the valuesFrom mechanism.


5-6: LGTM! API endpoint configuration successfully migrated to Helm values.

The migration from ConfigMap lookups to .Values._cluster keys for both api-server-endpoint and management-kubeconfig-endpoint is correct and consistent with the PR's architectural changes.

packages/apps/foundationdb/templates/cluster.yaml (1)

1-1: LGTM! Clean migration from ConfigMap lookup to values-based configuration.

The change correctly replaces the ConfigMap lookup with .Values._cluster "cluster-domain" while preserving the default value.

packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml (1)

1-1: LGTM! Correct migration from namespace annotation lookup to values-based configuration.

The change properly replaces the namespace annotation lookup with .Values._namespace.monitoring, aligning with the PR's valuesFrom mechanism.

packages/system/dashboard/templates/gatekeeper.yaml (1)

1-2: LGTM! Clean migration from ConfigMap lookups to values-based configuration.

Both configuration values are correctly migrated from ConfigMap lookups to .Values._cluster references, maintaining the existing conditional logic and URL construction.

packages/system/dashboard/templates/nginx-config.yaml (1)

1-1: LGTM! Clean migration from ConfigMap lookup to values-based configuration.

The change correctly replaces the ConfigMap lookup with .Values._cluster "root-host", maintaining consistency with the broader migration across dashboard templates.

packages/system/bucket/templates/ingress.yaml (1)

3-3: Good use of default value for issuerType.

The default value "http01" for .Values._cluster.clusterissuer ensures the template handles missing configuration gracefully.

packages/extra/monitoring/templates/alerta/alerta-db.yaml (1)

8-16: Well-structured defensive conditional logic.

The nested conditionals properly handle optional scheduling configuration. The template safely skips the topology spread constraints block if .Values._cluster.scheduling is absent or if globalAppTopologySpreadConstraints is not defined.

packages/apps/clickhouse/templates/chkeeper.yaml (1)

1-1: Good use of default value for cluster domain.

The default value "cozy.local" for .Values._cluster["cluster-domain"] ensures the template handles missing configuration gracefully, and the entire template is properly gated by the feature flag on line 3.

packages/extra/etcd/templates/etcd-cluster.yaml (1)

53-54: LGTM! Clean migration from ConfigMap lookup to values-based configuration.

The change correctly replaces ConfigMap-based scheduling constraint lookup with direct access to .Values._cluster.scheduling. The conditional logic and downstream processing remain consistent with the original behavior.

packages/extra/ingress/templates/nginx-ingress.yaml (1)

1-2: LGTM! Proper valuesFrom integration with values-based configuration.

The changes correctly implement the migration pattern:

  • Lines 1-2: Extract cluster configuration from .Values._cluster with appropriate defaults
  • Lines 26-28: Add valuesFrom to populate .Values._cluster from the cozystack-values Secret

This aligns with the PR's architecture of removing Helm lookups in favor of FluxCD's valuesFrom mechanism.

Also applies to: 26-28

packages/system/cozystack-api/templates/api-ingress.yaml (1)

1-3: LGTM! Correct migration to values-based cluster configuration.

The changes properly extract cluster configuration from .Values._cluster with appropriate defaults for expose-services and expose-ingress. The root-host value is used unconditionally (line 18), which assumes it will be provided by the parent HelmRelease's valuesFrom configuration.

packages/apps/postgres/templates/db.yaml (1)

49-50: LGTM! Consistent migration pattern for scheduling constraints.

The change correctly replaces ConfigMap-based lookup with .Values._cluster.scheduling access, matching the pattern used in other application templates (e.g., etcd). The conditional check ensures safe access to the nested scheduling configuration.

packages/apps/kubernetes/templates/cluster.yaml (2)

1-3: LGTM! Proper migration to namespace-scoped values.

The changes correctly replace Namespace annotation lookups with direct access to .Values._namespace for service references (etcd, ingress, host). These values are used unconditionally throughout the template (e.g., lines 126, 142, 143), which assumes they will be provided by the parent HelmRelease's valuesFrom configuration.


33-34: LGTM! Consistent scheduling constraint migration.

The change follows the established pattern for migrating scheduling constraints from ConfigMap lookups to .Values._cluster.scheduling, consistent with similar changes in etcd and postgres templates. The conditional check safely handles cases where scheduling configuration may not be present.

packages/extra/bootbox/templates/matchbox/ingress.yaml (2)

11-13: Conditional annotation logic is correct.

The acme.cert-manager.io/http01-ingress-class annotation is appropriately excluded when using the cloudflare issuer type, as cloudflare uses DNS-01 challenges rather than HTTP-01.


1-3: LGTM! Values correctly sourced from Helm values.

The migration from ConfigMap lookups to .Values._cluster and .Values._namespace is correct and aligns with the PR's architecture. The default value for issuerType ("http01") provides a sensible fallback. The cozystack-values Secret properly populates these paths via the tenant namespace template.

packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml (1)

1-5: LGTM! Correct migration to values-based configuration.

The replacement of ConfigMap lookups with .Values._cluster access is correct. The splitList usage properly handles comma-separated values from expose-services, and the conditional logic using has is the appropriate Helm function for checking list membership.

internal/controller/cozystackresourcedefinition_helmreconciler.go (3)

110-125: LGTM! Comprehensive equality check.

The valuesFromEqual() function correctly compares all fields of ValuesReference and optimizes by checking length first. The field-by-field comparison ensures accurate detection of differences.


184-190: LGTM! ValuesFrom synchronization correctly integrated.

The ValuesFrom synchronization logic properly:

  • Computes expected configuration via expectedValuesFrom()
  • Compares with current state using valuesFromEqual()
  • Updates when needed and sets the updated flag
  • Logs the update action at appropriate verbosity level

This integrates cleanly with the existing chart update flow.


100-108: No changes needed - ValuesReference configuration is correct and intentional.

The cozystack-values Secret consistently uses a single values.yaml key across all namespaces (verified in packages/core/platform/templates/ and packages/apps/tenant/templates/). The ValuesReference configuration correctly omits valuesKey and targetPath, which allows Flux to merge the entire Secret data at the root level of .Values as intended. This pattern is uniform across all HelmReleases in the codebase, confirming the design is deliberate.

packages/apps/bucket/templates/helmrelease.yaml (1)

24-26: LGTM! ValuesFrom correctly configured.

The addition of the valuesFrom block referencing the cozystack-values Secret aligns with the PR's architecture and matches the expected configuration enforced by the controller (see expectedValuesFrom() in cozystackresourcedefinition_helmreconciler.go).

packages/apps/tenant/templates/seaweedfs.yaml (1)

34-36: LGTM! Consistent valuesFrom configuration.

The valuesFrom block correctly references the cozystack-values Secret, consistent with the pattern applied across all HelmReleases in this PR.

packages/apps/tenant/templates/ingress.yaml (1)

34-36: LGTM! Clean migration to valuesFrom mechanism.

The addition of the valuesFrom block correctly references the cozystack-values Secret, enabling FluxCD to inject cluster and namespace configuration into the HelmRelease. This aligns with the PR's objective to replace Helm lookups with the valuesFrom mechanism.

packages/system/cert-manager-issuers/templates/cluster-issuers.yaml (1)

1-1: LGTM! Correct migration to values-based configuration.

The migration from ConfigMap lookup to .Values._cluster["clusterissuer"] with a default of "http01" is correct and aligns with the PR's objective to move configuration from runtime lookups to Helm values.

Note: The YAMLlint syntax error is a false positive—{{- is valid Helm template syntax.

packages/apps/tenant/templates/monitoring.yaml (1)

34-36: LGTM! Consistent valuesFrom implementation.

The addition of the valuesFrom block correctly references the cozystack-values Secret, maintaining consistency with other HelmRelease templates in this PR. This enables proper injection of cluster and namespace configuration.

packages/apps/vpn/templates/secret.yaml (1)

1-1: LGTM!

The migration from namespace annotation lookup to .Values._namespace.host is clean and aligns with the PR's objective to use FluxCD valuesFrom mechanism.

packages/system/keycloak-configure/templates/configure-kk.yaml (2)

1-2: LGTM!

The migration from ConfigMap lookups to .Values._cluster for host and redirect URIs is clean and follows the PR's valuesFrom pattern consistently.


9-21: The branding data structure is correct as implemented.

Verification confirms that .Values._cluster.branding is indeed a map containing a branding key, along with other fields like tenantText, footerText, titleText, logoText, logoSvg, and iconSvg. The code at line 20 ({{- $branding = $brandingConfig.branding }}) correctly accesses this nested field. The cozystack-branding ConfigMap data is injected into _cluster.branding via the platform chart, and each consumer (keycloak-configure and dashboard) accesses the appropriate fields for their needs.

packages/system/dashboard/templates/ingress.yaml (1)

1-4: LGTM!

The migration from ConfigMap lookups to .Values._cluster is clean and maintains the same default values. This aligns perfectly with the PR's objective to use FluxCD valuesFrom mechanism.

packages/extra/monitoring/templates/alerta/alerta.yaml (1)

1-3: LGTM!

The migration appropriately uses .Values._cluster for cluster-wide configuration (issuerType) and .Values._namespace for namespace-specific configuration (ingress, host). This follows the architecture described in the PR objectives.

packages/extra/monitoring/templates/grafana/db.yaml (1)

9-10: LGTM!

The migration from ConfigMap lookup to .Values._cluster.scheduling is clean and uses the get function appropriately to safely extract the nested globalAppTopologySpreadConstraints key.

packages/system/keycloak/templates/db.yaml (1)

9-17: LGTM! Proper defensive access to scheduling constraints.

The migration correctly checks for the existence of .Values._cluster.scheduling before attempting to access globalAppTopologySpreadConstraints. The use of the get function and conditional rendering ensures the template won't fail if the scheduling configuration is absent from the Secret.

packages/system/dashboard/templates/configmap.yaml (1)

1-1: LGTM! Safe migration with proper defaults at multiple levels.

The migration correctly uses a two-tier default strategy:

  1. Line 1 defaults to an empty dict if .Values._cluster.branding is missing
  2. Lines 19-24 provide field-level defaults using the existing fallback variables

This ensures the ConfigMap will render successfully even if the cozystack-values Secret doesn't contain branding configuration.

Also applies to: 19-24

packages/extra/seaweedfs/templates/seaweedfs.yaml (1)

62-64: LGTM! Correct addition of valuesFrom mechanism.

The valuesFrom block correctly references the cozystack-values Secret, aligning with the PR's objective to replace Helm lookup functions with FluxCD's valuesFrom mechanism.

packages/core/platform/templates/namespaces.yaml (2)

5-17: LGTM!

The cluster defaults dictionary provides sensible fallback values ensuring all required keys exist before merging with actual ConfigMap data. This prevents nil reference issues downstream.


55-75: LGTM!

The Secret cozystack-values is correctly structured with:

  • Proper namespace scoping
  • reconcile.fluxcd.io/watch: Enabled label for FluxCD integration
  • YAML structure with _cluster containing merged config plus optional branding/scheduling
pkg/registry/apps/application/rest.go (6)

151-154: LGTM!

Validation for reserved _-prefixed keys is correctly placed before the conversion to HelmRelease, returning a BadRequest error with a clear message.


450-453: LGTM!

Consistent validation in the Update path, matching the Create path behavior.


864-883: Top-level only filtering is consistent with validation.

The function correctly removes _-prefixed keys from the top level only. This matches the validation logic and the documented behavior that _cluster and _namespace are injected at the top level via valuesFrom.


885-900: LGTM!

The validation function correctly identifies reserved keys and provides a clear, actionable error message including the offending key name.


904-922: LGTM!

The filtered spec is correctly applied to strip internal keys when converting HelmRelease to Application, ensuring users don't see injected system values.


989-994: LGTM!

The ValuesFrom block correctly references the cozystack-values Secret. This ensures HelmReleases created via the API will automatically receive the namespace-scoped configuration. The Secret name is consistently used across all platform templates in the codebase.

packages/apps/nats/templates/nats.yaml (2)

1-1: LGTM!

The migration from ConfigMap lookup to .Values._cluster with a sensible default (cozy.local) is correct. The YAMLlint error is a false positive - this is valid Helm template syntax that will be rendered to proper YAML.


55-57: LGTM!

The valuesFrom block correctly references the cozystack-values Secret, enabling the HelmRelease to receive _cluster and _namespace values automatically.

packages/core/platform/templates/apps.yaml (2)

49-74: LGTM!

The Secret structure correctly includes both _cluster and _namespace sections with the tenant-root specific values hardcoded appropriately.


103-105: LGTM!

The valuesFrom block is correctly added to the tenant-root HelmRelease, enabling it to receive configuration from the cozystack-values Secret.

packages/apps/tenant/templates/namespace.yaml (3)

8-40: LGTM!

The computed values pattern is well-structured:

  • Values are computed once and reused in both Namespace labels and Secret
  • Parent namespace values are correctly inherited with | default ""
  • Service references (etcd, ingress, etc.) are overridden to tenant name when the tenant enables them

This is a clean refactoring that improves maintainability.


55-60: LGTM!

The labels correctly use the computed values for network policy references, ensuring consistency between Namespace labels and the Secret's _namespace content.


70-89: LGTM!

The cozystack-values Secret for tenant namespaces:

  • Correctly inherits _cluster from parent via .Values._cluster
  • Populates _namespace with the computed service references
  • Is created inside the conditional block (only for non-root tenants)

The static analysis error on line 2 is a false positive - this is valid Helm template syntax.

Comment on lines +77 to 79
{{- if .Values._cluster.scheduling -}}
{{- $dedicatedNodesForWindowsVMs := get .Values._cluster.scheduling "dedicatedNodesForWindowsVMs" -}}
{{- if eq $dedicatedNodesForWindowsVMs "true" -}}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the file
find . -name "_helpers.tpl" -path "*/vm-instance/*" -type f

Repository: cozystack/cozystack

Length of output: 113


🏁 Script executed:

# Also check the general structure of the packages/apps directory
find packages/apps -maxdepth 2 -type d | head -20

Repository: cozystack/cozystack

Length of output: 641


🏁 Script executed:

# Search for how _cluster.scheduling is populated
rg "_cluster\.scheduling|dedicatedNodesForWindowsVMs" --type yaml --type json --type helm -B 2 -A 2

Repository: cozystack/cozystack

Length of output: 91


🏁 Script executed:

# Read the actual _helpers.tpl file around lines 77-79
cat -n packages/apps/vm-instance/templates/_helpers.tpl | sed -n '70,85p'

Repository: cozystack/cozystack

Length of output: 681


🏁 Script executed:

# Search for how _cluster.scheduling is populated across the repo
rg "dedicatedNodesForWindowsVMs|_cluster.*scheduling" -B 3 -A 3 --type yaml --type json

Repository: cozystack/cozystack

Length of output: 5119


🏁 Script executed:

# Look for ConfigMap aggregation pattern - check for cozystack-scheduling or similar
fd "values\|schema\|configmap" packages/apps/ --type f | head -20

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

# Look for values.yaml files in vm-instance or parent charts
find packages/apps/vm-instance -name "values*.yaml" -o -name "Chart.yaml"

Repository: cozystack/cozystack

Length of output: 137


🏁 Script executed:

# Search for schema files that might define the data structure
find packages/apps/vm-instance -name "*.json" -o -name "*schema*"

Repository: cozystack/cozystack

Length of output: 107


🏁 Script executed:

# Look for upstream chart references and how values are aggregated
cat packages/apps/vm-instance/Chart.yaml 2>/dev/null || echo "No Chart.yaml found"

Repository: cozystack/cozystack

Length of output: 291


🏁 Script executed:

# Search for how _cluster values are injected across the repo
rg "\.Values\._cluster" -l | head -10

Repository: cozystack/cozystack

Length of output: 602


🏁 Script executed:

# Look for any test files or examples that show the data structure
find packages/apps/vm-instance -name "*.test.*" -o -name "*example*" -o -name "test*"

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

# Read the schema file to see the data type definition for dedicatedNodesForWindowsVMs
cat packages/apps/vm-instance/values.schema.json | head -100

Repository: cozystack/cozystack

Length of output: 2497


🏁 Script executed:

# Also check the values.yaml file
cat packages/apps/vm-instance/values.yaml

Repository: cozystack/cozystack

Length of output: 2544


🏁 Script executed:

# Search for how _cluster is injected - look for umbrella chart or parent values
find packages -name "Chart.yaml" -type f | xargs grep -l "dependencies\|aggregat" | head -5

Repository: cozystack/cozystack

Length of output: 365


🏁 Script executed:

# Search for the umbrella/parent chart that uses vm-instance as a dependency
find packages -name "Chart.yaml" -type f -exec grep -l "vm-instance" {} \;

Repository: cozystack/cozystack

Length of output: 141


🏁 Script executed:

# Look for the root or main chart
find . -maxdepth 3 -name "Chart.yaml" -type f | grep -E "^./[^/]+/Chart.yaml$|helm|umbrella"

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

# Search for where _cluster.scheduling is defined in values files
rg "scheduling:" -A 10 --type yaml | grep -A 10 "dedicatedNodesForWindowsVMs\|_cluster"

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

# Check vm-instance-rd to understand the dependency
cat packages/system/vm-instance-rd/Chart.yaml

Repository: cozystack/cozystack

Length of output: 198


🏁 Script executed:

# Search directly for dedicatedNodesForWindowsVMs in the entire repo
rg "dedicatedNodesForWindowsVMs" -B 5 -A 5

Repository: cozystack/cozystack

Length of output: 3954


🏁 Script executed:

# Look for cozystack-values or ConfigMap aggregation
rg "cozystack-values|aggregat" --type yaml -B 2 -A 2 | head -50

Repository: cozystack/cozystack

Length of output: 6087


🏁 Script executed:

# Check root directory structure for umbrella chart
ls -la | head -20

Repository: cozystack/cozystack

Length of output: 1248


🏁 Script executed:

# Look for any documentation or scripts that explain the architecture
find . -maxdepth 2 -name "README*" -o -name "ARCHITECTURE*" -o -name "*aggregate*"

Repository: cozystack/cozystack

Length of output: 74


🏁 Script executed:

# Search for cozystack-scheduling ConfigMap definition or creation
rg "cozystack-scheduling" -B 3 -A 3

Repository: cozystack/cozystack

Length of output: 2239


🏁 Script executed:

# Look for build scripts or value aggregation logic
find . -maxdepth 2 -name "Makefile" -o -name "*.sh" -o -name "*build*" -o -name "*aggregate*" | head -10

Repository: cozystack/cozystack

Length of output: 305


🏁 Script executed:

# Check the Makefile for clues about value aggregation
cat Makefile

Repository: cozystack/cozystack

Length of output: 2052


🏁 Script executed:

# Look at how the ConfigMap is read and aggregated into _cluster.scheduling
cat packages/core/platform/templates/apps.yaml | head -100

Repository: cozystack/cozystack

Length of output: 3093


🏁 Script executed:

# Also check the namespaces.yaml for the pattern
cat packages/core/platform/templates/namespaces.yaml | head -100

Repository: cozystack/cozystack

Length of output: 2674


🏁 Script executed:

# Search for where _cluster.scheduling is populated from the ConfigMap
rg "_cluster.scheduling" -B 10 -A 10 packages/core/platform/

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

# Now let's find where cozystack-scheduling ConfigMap is defined
rg "cozystack-scheduling" -B 5 -A 10 | grep -v "^--$"

Repository: cozystack/cozystack

Length of output: 5229


🏁 Script executed:

# Also check for any ConfigMap or configuration examples
find packages/core -name "*.yaml" -type f | xargs grep -l "cozystack-scheduling"

Repository: cozystack/cozystack

Length of output: 154


🏁 Script executed:

# Let's examine the exact code path for how the ConfigMap data becomes YAML values
cat -n packages/core/platform/templates/apps.yaml | sed -n '1,80p'

Repository: cozystack/cozystack

Length of output: 3204


🏁 Script executed:

# Let's also check if there are any tests or examples showing the actual data structure
find . -name "*.md" -o -name "*test*" | xargs grep -l "dedicatedNodesForWindowsVMs\|cozystack-scheduling" 2>/dev/null | head -5

Repository: cozystack/cozystack

Length of output: 91


🏁 Script executed:

# Let's search for the actual ConfigMap definition or any defaults
find packages/core -type f \( -name "*.yaml" -o -name "*.yml" \) -exec grep -l "scheduling:" {} \;

Repository: cozystack/cozystack

Length of output: 154


🏁 Script executed:

# Let's understand how the data flows: ConfigMap -> Secret -> Helm values
# Let's check if there are any examples or documentation about how boolean values are handled
rg "toYaml|fromYaml" packages/core/platform/templates/ -B 2 -A 2

Repository: cozystack/cozystack

Length of output: 4723


🏁 Script executed:

# Check if there's a schema or configuration guide for cozystack-scheduling
find . -type f \( -name "*.md" -o -name "*.txt" -o -name "*.rst" \) | xargs grep -l "scheduling\|cozystack-scheduling" 2>/dev/null | head -5

Repository: cozystack/cozystack

Length of output: 330


🏁 Script executed:

# Let's verify how Helm's toYaml and eq work with boolean values
# Create a simple test to understand the type behavior
python3 << 'EOF'
import json

# Simulate what happens when ConfigMap data goes through toYaml
# ConfigMap stores everything as strings
configmap_data = {
    "dedicatedNodesForWindowsVMs": "true"  # This is a STRING in ConfigMap
}

# When toYaml converts a string "true" to YAML, what happens?
# YAML spec says bare "true" is a boolean, but quoted "true" is a string

# When Helm reads the YAML back from the Secret, it will parse:
# If output is: dedicatedNodesForWindowsVMs: true  (boolean in YAML)
# Then Helm sees it as boolean true

# If output is: dedicatedNodesForWindowsVMs: "true"  (string in YAML)  
# Then Helm sees it as string "true"

print("ConfigMap stores:", json.dumps(configmap_data))
print()
print("When toYaml outputs the ConfigMap data:")
print("- If string 'true' becomes YAML boolean: true -> Helm reads as boolean")
print("- If string 'true' becomes YAML string: \"true\" -> Helm reads as string")
print()
print("The comparison: eq $value \"true\"")
print("- Works if $value is string \"true\"")
print("- Fails if $value is boolean true")
EOF

Repository: cozystack/cozystack

Length of output: 406


🏁 Script executed:

# Let's verify this by checking how Helm's toYaml actually works with ConfigMap data
# Search for any TODOs, FIXMEs, or known issues related to this
rg "TODO|FIXME|BUG|windows.*affinity|dedicatedNodes" packages/apps/ packages/system/ -i

Repository: cozystack/cozystack

Length of output: 50375


🏁 Script executed:

# Let's also check the virtual-machine chart to see if it has the same issue
cat -n packages/apps/virtual-machine/templates/_helpers.tpl | sed -n '70,85p'

Repository: cozystack/cozystack

Length of output: 681


🏁 Script executed:

# Search for any tests or real-world configs that might reveal the actual data type
find . -name "*.yaml" -o -name "*.yml" | xargs grep -l "dedicatedNodesForWindowsVMs" 2>/dev/null

Repository: cozystack/cozystack

Length of output: 47


Fix boolean comparison for Windows VM node affinity.

Lines 79 and the identical code in packages/apps/virtual-machine/templates/_helpers.tpl compare $dedicatedNodesForWindowsVMs using eq $dedicatedNodesForWindowsVMs "true". However, the value flows through toYaml in the platform template (apps.yaml line 67), which converts the ConfigMap string "true" into bare YAML true without quotes. When Helm parses this YAML, it becomes a boolean true, causing the comparison to fail since eq boolean_true "true" is false.

Replace with either a truthy check:

{{- if $dedicatedNodesForWindowsVMs -}}

Or explicit string conversion:

{{- if eq (toString $dedicatedNodesForWindowsVMs) "true" -}}

Apply the same fix to packages/apps/virtual-machine/templates/_helpers.tpl line 79.

🤖 Prompt for AI Agents
In packages/apps/vm-instance/templates/_helpers.tpl around lines 77–79 (and
mirror the same change in packages/apps/virtual-machine/templates/_helpers.tpl
line 79), the template currently compares $dedicatedNodesForWindowsVMs to the
string "true", which fails when the value is a boolean; change the conditional
to either a truthy check (use the variable directly in the if) or convert it to
string before comparing (use toString on the variable and compare to "true") so
the check works for both boolean and string inputs.

Comment on lines 19 to 21
{{- $host := "example.org" }}
{{- $host := "example.org" }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Duplicate variable declaration.

Line 20 duplicates line 19. This appears to be an accidental duplicate that should be removed.

🔎 Suggested fix
 {{- $host := "example.org" }}
-{{- $host := "example.org" }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $host := "example.org" }}
{{- $host := "example.org" }}
{{- $host := "example.org" }}
🤖 Prompt for AI Agents
In packages/core/platform/templates/apps.yaml around lines 19 to 20, there is a
duplicate Helm variable declaration for $host on line 20 that repeats the
declaration on line 19; remove the redundant second declaration (line 20) so
$host is declared only once and ensure surrounding template syntax/whitespace
remains unchanged.

Comment on lines +37 to +38
{{- $ingress := .Values._namespace.ingress }}
{{- $host := .Values._namespace.host }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add defaults for _namespace.ingress and _namespace.host to prevent template failures.

Lines 37-38 access .Values._namespace.ingress and .Values._namespace.host without defaults. If the cozystack-values Secret does not populate the _namespace section with these keys, template rendering will fail at line 135 where $ingress is used directly for the ingress className.

While lines 136 and 144 include fallback patterns for the host (.Values.host | default (printf "s3.%s" $host)), the assignment of $host itself on line 38 should include a fallback to ensure robustness.

🔎 Proposed fix
-{{- $ingress := .Values._namespace.ingress }}
-{{- $host := .Values._namespace.host }}
+{{- $ingress := .Values._namespace.ingress | default "nginx" }}
+{{- $host := .Values._namespace.host | default "" }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $ingress := .Values._namespace.ingress }}
{{- $host := .Values._namespace.host }}
{{- $ingress := .Values._namespace.ingress | default "nginx" }}
{{- $host := .Values._namespace.host | default "" }}
🤖 Prompt for AI Agents
In packages/extra/seaweedfs/templates/seaweedfs.yaml around lines 37-38, the
template assigns $ingress and $host from .Values._namespace.ingress and
.Values._namespace.host without defaults which can cause rendering failures;
change those assignments to use Helm's default function so $ingress defaults to
an empty map/string (or sensible default) and $host falls back to a safe value
(e.g., empty string or namespace) when .Values._namespace.host is missing,
ensuring subsequent uses (like ingress className and host formatting) always
have a defined value.

Comment on lines +1 to +2
{{- $host := index .Values._cluster "root-host" }}
{{- $extraRedirectUris := splitList "," ((index .Values._cluster "extra-keycloak-redirect-uri-for-dashboard") | default "") }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add a default value for root-host to prevent invalid redirect URIs.

The migration from ConfigMap lookup to .Values._cluster access is correct, but root-host lacks a default value while extra-keycloak-redirect-uri-for-dashboard has one. If root-host is not provided, lines 66 and 71 will generate invalid URIs like https://dashboard. (note the trailing dot), which will break the OAuth authentication flow for the dashboard.

🔎 Proposed fix

Add a sensible default:

-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := (index .Values._cluster "root-host") | default "cozy.local" }}
 {{- $extraRedirectUris := splitList "," ((index .Values._cluster "extra-keycloak-redirect-uri-for-dashboard") | default "") }}

Or add validation to fail early with a clear error:

+{{- if not (index .Values._cluster "root-host") }}
+{{- fail "root-host must be set in cluster configuration" }}
+{{- end }}
 {{- $host := index .Values._cluster "root-host" }}
 {{- $extraRedirectUris := splitList "," ((index .Values._cluster "extra-keycloak-redirect-uri-for-dashboard") | default "") }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{{- $host := index .Values._cluster "root-host" }}
{{- $extraRedirectUris := splitList "," ((index .Values._cluster "extra-keycloak-redirect-uri-for-dashboard") | default "") }}
{{- $host := (index .Values._cluster "root-host") | default "cozy.local" }}
{{- $extraRedirectUris := splitList "," ((index .Values._cluster "extra-keycloak-redirect-uri-for-dashboard") | default "") }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

{{- $host := index $cozyConfig.data "root-host" }}
{{- $issuerType := (index $cozyConfig.data "clusterissuer") | default "http01" }}
{{- $exposeIngress := index $cozyConfig.data "expose-ingress" | default "tenant-root" }}
{{- $host := index .Values._cluster "root-host" }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add default for root-host to prevent template failure.

Line 1 accesses .Values._cluster "root-host" without a default, while lines 2-3 provide defaults for their respective values. If the cozystack-values Secret does not populate root-host, template rendering will fail when $host is used at lines 21 and 24.

🔎 Proposed fix
-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := (index .Values._cluster "root-host") | default "example.com" }}

Note: Choose an appropriate default value based on your environment or consider making this validation explicit if root-host is truly required.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
In packages/system/keycloak/templates/ingress.yaml around line 1, the template
assigns $host from .Values._cluster "root-host" without a fallback which can
cause rendering to fail later (used at lines 21 and 24); change the assignment
to provide a sensible default or explicit validation: use Helm's
default/coalesce mechanism to supply a fallback host (or add a clear
validation/error message if root-host is required) so the template always has a
value when rendering.

{{- $apiServerEndpoint = $managementKubeconfigEndpoint }}
{{- end }}
{{- $k8sClient := index $k8sClientSecret.data "client-secret-key" | b64dec }}
{{- $rootSaConfigMap := lookup "v1" "ConfigMap" "kube-system" "kube-root-ca.crt" }}
Copy link
Member

Choose a reason for hiding this comment

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

rootSaConfigMap has a typo. Also every k8s namespace contains this configmap, looking it up is not necessary. It can be referenced with valueFrom.

Copy link
Member Author

Choose a reason for hiding this comment

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

Replace Helm lookup functions with FluxCD valuesFrom mechanism for
reading cluster and namespace configuration.

Changes:
- Create Secret cozystack-values in each namespace with values.yaml key
  containing _cluster and _namespace configuration as nested YAML
- Configure HelmReleases to read from this Secret via valuesFrom
  (valuesKey defaults to values.yaml, so it can be omitted)
- Update cozy-lib helpers to access config via .Values._cluster
- Add default values for required _cluster keys to ensure all fields exist
- Update Go code (cozystack-api and helm reconciler) to use new format

This eliminates the need for Helm lookup functions while maintaining
the same configuration interface for charts.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
@kvaps kvaps force-pushed the replace-lookup-with-valuesfrom branch from 2e79023 to 2e61810 Compare January 5, 2026 15:11
Copy link
Contributor

@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

Fix all issues with AI Agents 🤖
In @packages/core/platform/templates/namespaces.yaml:
- Around line 55-75: The Secret "cozystack-values" only defines the _cluster
block and omits _namespace, which causes HelmReleases consuming
.Values._namespace.* (e.g., host, etcd, ingress, seaweedfs) to get nil; update
the template producing the Secret (cozystack-values) or downstream HelmRelease
templates to handle missing _namespace: either add a safe default _namespace
block alongside _cluster in the cozystack-values Secret generation (mirroring
tenant template) or modify consuming charts/templates to use defaulting
functions or conditional checks when accessing .Values._namespace (e.g., guard
expressions or helm default function around
.Values._namespace.host/etcd/ingress/seaweedfs) so undefined values do not cause
nil derefs.

In @packages/system/bucket/templates/ingress.yaml:
- Around line 1-2: The template currently grabs .Values._namespace.host and
.Values._namespace.ingress without defaults causing render failures when those
keys are absent; change the variable assignments to use Helm's default function
(e.g. set $host := default "" .Values._namespace.host and set $ingress :=
default false .Values._namespace.ingress or another sensible default like an
empty map/string) so references to $host and $ingress (and the existing
clusterissuer logic) won't break if the Secret omits those keys; update any
downstream logic that expects a non-empty value to handle the chosen default.
♻️ Duplicate comments (6)
packages/extra/seaweedfs/templates/seaweedfs.yaml (1)

37-38: Add defaults to prevent template rendering failures.

These lines access .Values._namespace.ingress and .Values._namespace.host without defaults. If the cozystack-values Secret is missing these keys, template rendering will fail at line 135 where $ingress is used directly for className.

🔎 Proposed fix
-{{- $ingress := .Values._namespace.ingress }}
-{{- $host := .Values._namespace.host }}
+{{- $ingress := .Values._namespace.ingress | default "nginx" }}
+{{- $host := .Values._namespace.host | default "" }}
packages/system/keycloak/templates/sts.yaml (1)

1-2: Add a default value for root-host to prevent invalid configuration.

As noted in the previous review, root-host lacks a default value while cluster-domain has one. If root-host is not provided in .Values._cluster, line 123 will generate an invalid KC_HOSTNAME value like https://keycloak. (with a trailing dot), causing Keycloak to fail at startup.

🔎 Suggested fixes

Option 1: Provide a sensible default

-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := (index .Values._cluster "root-host") | default "cozy.local" }}
 {{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}

Option 2: Fail early with a clear error message

+{{- if not (index .Values._cluster "root-host") }}
+{{- fail "root-host must be set in cluster configuration" }}
+{{- end }}
 {{- $host := index .Values._cluster "root-host" }}
 {{- $clusterDomain := (index .Values._cluster "cluster-domain") | default "cozy.local" }}
packages/system/keycloak/templates/ingress.yaml (1)

1-1: Add default for root-host to prevent template failure.

Line 1 accesses .Values._cluster "root-host" without a default, while lines 2-3 provide defaults for their respective values. If the cozystack-values Secret does not populate root-host, template rendering will fail when $host is used at lines 21 and 24.

🔎 Proposed fix
-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := (index .Values._cluster "root-host") | default "example.local" }}
packages/apps/bucket/templates/bucketclaim.yaml (1)

1-1: Add required validation for seaweedfs namespace value.

.Values._namespace.seaweedfs is used without validation or a default. If this value is missing from the cozystack-values Secret, the BucketClaim and BucketAccess resources will have empty class names at lines 7 and 16, causing failures.

🔎 Proposed fix to validate required value
-{{- $seaweedfs := .Values._namespace.seaweedfs }}
+{{- $seaweedfs := .Values._namespace.seaweedfs | required ".Values._namespace.seaweedfs is required for bucket storage configuration" }}
packages/core/platform/templates/apps.yaml (1)

20-21: Remove duplicate variable declaration.

Line 21 duplicates line 20. Remove the redundant declaration.

🔎 Proposed fix
 {{- $host := "example.org" }}
-{{- $host := "example.org" }}
packages/system/dashboard/templates/keycloakclient.yaml (1)

1-2: Add a default value or validation for root-host.

The previous review comment about the missing default for root-host remains unaddressed. Without a default value, lines 66 and 71 will generate invalid redirect URIs like https://dashboard. when root-host is not provided in the cluster configuration, breaking OAuth authentication for the dashboard.

Please either add a sensible default (e.g., | default "cozy.local") or add validation to fail early with a clear error message.

🔎 Proposed fixes

Option 1: Add a default value

-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := (index .Values._cluster "root-host") | default "cozy.local" }}
 {{- $extraRedirectUris := splitList "," ((index .Values._cluster "extra-keycloak-redirect-uri-for-dashboard") | default "") }}

Option 2: Add validation

+{{- if not (index .Values._cluster "root-host") }}
+{{- fail "root-host must be set in cluster configuration" }}
+{{- end }}
 {{- $host := index .Values._cluster "root-host" }}
 {{- $extraRedirectUris := splitList "," ((index .Values._cluster "extra-keycloak-redirect-uri-for-dashboard") | default "") }}
🧹 Nitpick comments (4)
packages/extra/monitoring/templates/grafana/grafana.yaml (1)

1-3: Consider adding a default for $ingress for consistency and resilience.

Line 1 provides a default for $issuerType, but lines 2-3 do not provide defaults for $ingress and $host. While $host has fallbacks via .Values.host | default $host pattern (lines 25, 82, 94), $ingress is used directly on lines 76 and 80 without any fallback.

If the cozystack-values Secret is misconfigured or the _namespace.ingress key is missing, this could result in an empty ingress class name.

🔎 Suggested fix for consistency
 {{- $issuerType := (index .Values._cluster "clusterissuer") | default "http01" }}
-{{- $ingress := .Values._namespace.ingress }}
-{{- $host := .Values._namespace.host }}
+{{- $ingress := .Values._namespace.ingress | default "" }}
+{{- $host := .Values._namespace.host | default "" }}
pkg/registry/apps/application/rest.go (1)

864-900: Clarify: validation only checks top-level keys.

Both filterInternalKeys and validateNoInternalKeys only process top-level keys in the JSON object. Nested keys like {"foo": {"_internal": "value"}} will pass validation and won't be filtered.

If this is intentional (only top-level keys are reserved), consider adding a brief comment to document this behavior. If nested keys should also be checked, a recursive implementation would be needed.

🔎 Optional: Add clarifying comment
 // filterInternalKeys removes keys starting with "_" from the JSON values
+// Note: Only top-level keys are filtered; nested keys are preserved.
 func filterInternalKeys(values *apiextv1.JSON) *apiextv1.JSON {
 // validateNoInternalKeys checks that values don't contain keys starting with "_"
+// Note: Only top-level keys are validated; nested keys are allowed.
 func validateNoInternalKeys(values *apiextv1.JSON) error {
packages/system/keycloak-configure/templates/configure-kk.yaml (1)

8-20: Good fix for branding extraction, but add quote filters.

The branding extraction at line 19 correctly addresses the previous review comment by accessing $brandingConfig.branding instead of using the entire map.

However, lines 55-56 should use the quote filter to safely handle empty strings or special characters:

🔎 Recommended enhancement to add quote filters
   {{- if $branding }}
-  displayHtmlName: {{ $branding }}
-  displayName: {{ $branding }}
+  displayHtmlName: {{ $branding | quote }}
+  displayName: {{ $branding | quote }}
   {{- end }}
packages/apps/tenant/templates/namespace.yaml (1)

80-88: Consider guarding against nil _cluster values.

If .Values._cluster is nil (e.g., when the parent Secret is missing or malformed), toYaml will produce an empty string, resulting in an invalid YAML structure under _cluster:. Consider adding a guard or default.

🔎 Proposed defensive guard
   values.yaml: |
     _cluster:
-      {{- .Values._cluster | toYaml | nindent 6 }}
+      {{- (.Values._cluster | default dict) | toYaml | nindent 6 }}
     _namespace:
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e79023 and 2e61810.

📒 Files selected for processing (59)
  • cmd/cozystack-controller/main.go
  • internal/controller/cozystackresourcedefinition_helmreconciler.go
  • internal/controller/system_helm_reconciler.go
  • internal/controller/tenant_helm_reconciler.go
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/apps/postgres/templates/db.yaml
  • packages/apps/tenant/templates/etcd.yaml
  • packages/apps/tenant/templates/info.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/virtual-machine/templates/_helpers.tpl
  • packages/apps/vm-instance/templates/_helpers.tpl
  • packages/apps/vpn/templates/secret.yaml
  • packages/core/platform/templates/apps.yaml
  • packages/core/platform/templates/helmreleases.yaml
  • packages/core/platform/templates/namespaces.yaml
  • packages/extra/bootbox/templates/matchbox/ingress.yaml
  • packages/extra/bootbox/templates/matchbox/machines.yaml
  • packages/extra/etcd/templates/etcd-cluster.yaml
  • packages/extra/info/templates/dashboard-resourcemap.yaml
  • packages/extra/info/templates/kubeconfig.yaml
  • packages/extra/ingress/templates/nginx-ingress.yaml
  • packages/extra/monitoring/templates/alerta/alerta-db.yaml
  • packages/extra/monitoring/templates/alerta/alerta.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/extra/seaweedfs/templates/client/cosi-deployment.yaml
  • packages/extra/seaweedfs/templates/ingress.yaml
  • packages/extra/seaweedfs/templates/seaweedfs.yaml
  • packages/library/cozy-lib/templates/_cozyconfig.tpl
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
  • packages/tests/cozy-lib-tests/tests/quota_values.yaml
  • pkg/registry/apps/application/rest.go
💤 Files with no reviewable changes (3)
  • cmd/cozystack-controller/main.go
  • internal/controller/tenant_helm_reconciler.go
  • internal/controller/system_helm_reconciler.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • internal/controller/cozystackresourcedefinition_helmreconciler.go
  • packages/extra/seaweedfs/templates/client/cosi-deployment.yaml
  • packages/apps/tenant/templates/info.yaml
  • packages/extra/etcd/templates/etcd-cluster.yaml
  • packages/tests/cozy-lib-tests/tests/quota_values.yaml
  • packages/apps/vm-instance/templates/_helpers.tpl
  • packages/apps/tenant/templates/monitoring.yaml
  • packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml
  • packages/apps/postgres/templates/db.yaml
🧰 Additional context used
📓 Path-based instructions (6)
**/*.yaml

📄 CodeRabbit inference engine (AGENTS.md)

Do NOT directly edit upstream Helm charts in vendored charts directory; use proper chart vendoring mechanisms

Files:

  • packages/extra/monitoring/templates/alerta/alerta.yaml
  • packages/system/dashboard/templates/ingress.yaml
  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/core/platform/templates/helmreleases.yaml
  • packages/extra/seaweedfs/templates/ingress.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/extra/monitoring/templates/alerta/alerta-db.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/extra/info/templates/kubeconfig.yaml
  • packages/apps/tenant/templates/ingress.yaml
  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/extra/bootbox/templates/matchbox/ingress.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/extra/ingress/templates/nginx-ingress.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
  • packages/core/platform/templates/namespaces.yaml
  • packages/extra/seaweedfs/templates/seaweedfs.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/core/platform/templates/apps.yaml
  • packages/apps/tenant/templates/etcd.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/extra/bootbox/templates/matchbox/machines.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/vpn/templates/secret.yaml
  • packages/extra/info/templates/dashboard-resourcemap.yaml
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
packages/system/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/system/dashboard/templates/ingress.yaml
  • packages/system/keycloak/templates/sts.yaml
  • packages/system/dashboard/templates/gatekeeper.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/system/dashboard/templates/configmap.yaml
  • packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/bucket/templates/ingress.yaml
  • packages/system/cert-manager-issuers/templates/cluster-issuers.yaml
  • packages/system/cozystack-api/templates/api-ingress.yaml
  • packages/system/dashboard/templates/keycloakclient.yaml
  • packages/system/dashboard/templates/nginx-config.yaml
  • packages/system/keycloak/templates/db.yaml
  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
packages/apps/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/apps/clickhouse/templates/clickhouse.yaml
  • packages/apps/tenant/templates/namespace.yaml
  • packages/apps/bucket/templates/bucketclaim.yaml
  • packages/apps/ferretdb/templates/postgres.yaml
  • packages/apps/virtual-machine/templates/_helpers.tpl
  • packages/apps/tenant/templates/ingress.yaml
  • packages/apps/tenant/templates/seaweedfs.yaml
  • packages/apps/kubernetes/templates/ingress.yaml
  • packages/apps/tenant/templates/etcd.yaml
  • packages/apps/bucket/templates/helmrelease.yaml
  • packages/apps/nats/templates/nats.yaml
  • packages/apps/clickhouse/templates/chkeeper.yaml
  • packages/apps/foundationdb/templates/cluster.yaml
  • packages/apps/kubernetes/templates/cluster.yaml
  • packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml
  • packages/apps/tenant/templates/keycloakgroups.yaml
  • packages/apps/vpn/templates/secret.yaml
packages/core/**

📄 CodeRabbit inference engine (AGENTS.md)

Use Helm Chart umbrella pattern with vendored upstream charts in charts/ directory

Files:

  • packages/core/platform/templates/helmreleases.yaml
  • packages/core/platform/templates/namespaces.yaml
  • packages/core/platform/templates/apps.yaml
pkg/**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Follow controller-runtime patterns and kubebuilder style for Go code in pkg directory

Files:

  • pkg/registry/apps/application/rest.go
**/*.go

📄 CodeRabbit inference engine (AGENTS.md)

Do NOT manually edit vendor/ directory or auto-generated files (zz_generated.*.go)

Files:

  • pkg/registry/apps/application/rest.go
🧠 Learnings (4)
📚 Learning: 2025-07-03T05:54:51.264Z
Learnt from: NickVolynkin
Repo: cozystack/cozystack PR: 1120
File: packages/apps/clickhouse/README.md:60-67
Timestamp: 2025-07-03T05:54:51.264Z
Learning: The `cozy-lib.resources.sanitize` function in packages/library/cozy-lib/templates/_resources.tpl supports both standard Kubernetes resource format (with limits:/requests: sections) and flat format (direct resource specifications). The flat format takes priority over nested values. CozyStack apps include cozy-lib as a chart dependency through symlinks in packages/apps/*/charts/cozy-lib directories.

Applied to files:

  • packages/library/cozy-lib/templates/_cozyconfig.tpl
📚 Learning: 2025-11-28T21:26:10.771Z
Learnt from: kvaps
Repo: cozystack/cozystack PR: 1671
File: packages/apps/postgres/files/versions.yaml:1-6
Timestamp: 2025-11-28T21:26:10.771Z
Learning: In packages/apps/postgres/files/versions.yaml, the version mappings are sourced from the CloudNativePG container registry (ghcr.io/cloudnative-pg/postgresql), not from PostgreSQL project releases. The versions should reflect what's actually published in the CloudNativePG registry, which is automatically fetched by the hack/update-versions.sh script.

Applied to files:

  • packages/apps/ferretdb/templates/postgres.yaml
📚 Learning: 2025-07-26T18:26:01.447Z
Learnt from: NickVolynkin
Repo: cozystack/cozystack PR: 1216
File: packages/extra/monitoring/README.md:30-31
Timestamp: 2025-07-26T18:26:01.447Z
Learning: The cozyvalues-gen tool has a known issue (https://github.com/cozystack/cozyvalues-gen/issues/10) where it incorrectly places Grafana configuration entries under the wrong documentation sections, specifically placing grafana.resources.requests.* entries in the Metrics storage configuration table instead of the Grafana configuration table.

Applied to files:

  • packages/extra/monitoring/templates/grafana/grafana.yaml
  • packages/extra/monitoring/templates/grafana/db.yaml
📚 Learning: 2025-07-11T06:28:13.696Z
Learnt from: lllamnyp
Repo: cozystack/cozystack PR: 1160
File: packages/system/hetzner-robotlb/charts/robotlb/templates/role.yaml:6-8
Timestamp: 2025-07-11T06:28:13.696Z
Learning: In Helm templates, the `{{-` directive chomps all leading whitespace including newlines back to the previous content, so `{{- toYaml .Values.something | nindent 2 }}` will render correctly even with apparent indentation issues. However, for better style, it's cleaner to put the template directive on the same line as the parent key (e.g., `rules: {{- toYaml .Values.serviceAccount.permissions | nindent 2 }}`).

Applied to files:

  • packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml
🧬 Code graph analysis (1)
pkg/registry/apps/application/rest.go (2)
pkg/apis/apps/v1alpha1/types.go (1)
  • Application (66-74)
pkg/generated/applyconfiguration/apps/v1alpha1/application.go (1)
  • Application (39-46)
🪛 YAMLlint (1.37.1)
packages/extra/monitoring/templates/alerta/alerta.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/clickhouse/templates/clickhouse.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/seaweedfs/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/tenant/templates/namespace.yaml

[error] 2-2: syntax error: expected '', but found '{'

(syntax)

packages/apps/bucket/templates/bucketclaim.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/monitoring/templates/alerta/alerta-db.yaml

[error] 9-9: syntax error: could not find expected ':'

(syntax)

packages/system/keycloak/templates/sts.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/gatekeeper.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak-configure/templates/configure-kk.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/info/templates/kubeconfig.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/monitoring/templates/grafana/grafana.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/bootbox/templates/matchbox/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/configmap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)


[warning] 22-22: too many spaces after colon

(colons)


[warning] 23-23: too many spaces after colon

(colons)


[warning] 24-24: too many spaces after colon

(colons)

packages/extra/ingress/templates/nginx-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/monitoring/templates/grafana/db.yaml

[error] 10-10: syntax error: could not find expected ':'

(syntax)

packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/bootbox/templates/matchbox/machines.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/nats/templates/nats.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/clickhouse/templates/chkeeper.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/foundationdb/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/cluster.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/tenant/templates/keycloakgroups.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/apps/vpn/templates/secret.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/extra/info/templates/dashboard-resourcemap.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/bucket/templates/ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/cert-manager-issuers/templates/cluster-issuers.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/cozystack-api/templates/api-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/keycloakclient.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/dashboard/templates/nginx-config.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

packages/system/keycloak/templates/db.yaml

[error] 10-10: syntax error: could not find expected ':'

(syntax)

packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Install Cozystack
🔇 Additional comments (54)
packages/system/dashboard/templates/nginx-config.yaml (1)

1-1: Verify valuesFrom configuration and consider adding a default value.

The change correctly implements the PR objective by replacing the Helm lookup with .Values._cluster["root-host"]. However, the template will fail at render time if the key doesn't exist.

Please verify:

  1. The HelmRelease for this chart includes a valuesFrom reference to the cozystack-values Secret
  2. The Secret's _cluster data contains the root-host key

Optionally, consider adding a default value for robustness:

🔎 Proposed enhancement with default value
-{{- $host := index .Values._cluster "root-host" }}
+{{- $host := index .Values._cluster "root-host" | default "example.com" }}
packages/apps/kubernetes/templates/ingress.yaml (1)

1-1: Verify that .Values._namespace.ingress is always populated.

The change correctly implements the new valuesFrom pattern. However, ensure that the Secret cozystack-values always includes the _namespace.ingress field, as an empty or missing value would result in an invalid ingressClassName at line 18.

Optional: Add defensive validation

If you want to add an extra safety check, consider validating the value exists:

-{{- $ingress := .Values._namespace.ingress }}
+{{- if not .Values._namespace.ingress }}
+{{- fail "Missing required value: .Values._namespace.ingress" }}
+{{- end }}
+{{- $ingress := .Values._namespace.ingress }}

However, if the controller guarantees the Secret structure, this may be unnecessary.

Based on PR architecture, where the controller validates HelmRelease valuesFrom configuration.

packages/apps/tenant/templates/etcd.yaml (1)

34-36: LGTM! Clean integration of valuesFrom mechanism.

The addition of the valuesFrom block correctly references the cozystack-values Secret, enabling the HelmRelease to receive configuration from the centralized Secret as intended by this PR.

packages/extra/seaweedfs/templates/seaweedfs.yaml (1)

62-64: LGTM! Correct valuesFrom integration.

The valuesFrom block properly references the cozystack-values Secret, enabling configuration propagation as intended.

packages/apps/clickhouse/templates/clickhouse.yaml (1)

1-1: LGTM! Clean migration to values-based configuration.

The replacement of ConfigMap lookup with .Values._cluster.cluster-domain includes a sensible default value ("cozy.local"), ensuring the template remains robust if the key is missing.

Note: The YAMLlint syntax error is a false positive caused by Go template directives, which are valid in Helm templates.

packages/apps/foundationdb/templates/cluster.yaml (1)

1-1: LGTM! Proper values-based configuration with fallback.

The migration from ConfigMap lookup to .Values._cluster.cluster-domain includes an appropriate default ("cozy.local"), ensuring the template functions correctly even if the Secret key is absent.

Note: The YAMLlint syntax error is a false positive resulting from Go template syntax.

packages/apps/tenant/templates/seaweedfs.yaml (1)

34-36: LGTM! Correct valuesFrom implementation.

The valuesFrom block correctly integrates the cozystack-values Secret reference, enabling centralized configuration management consistent with the PR's architecture.

packages/system/cert-manager-issuers/templates/cluster-issuers.yaml (1)

1-1: LGTM!

The migration from ConfigMap lookup to .Values._cluster with a sensible default ("http01") is correct and aligns with the PR objectives. The conditional logic for solver selection remains intact.

packages/extra/info/templates/dashboard-resourcemap.yaml (1)

1-1: LGTM!

The migration from ConfigMap to .Values._cluster is correct. The absence of a default for oidc-enabled is appropriate since OIDC is optional, and the conditional logic properly handles both enabled and disabled states.

packages/apps/tenant/templates/keycloakgroups.yaml (1)

1-1: LGTM!

The migration to .Values._cluster is correct. The conditional rendering (line 2) appropriately skips KeycloakRealmGroup resources when OIDC is not enabled, making the absence of a default acceptable.

packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml (1)

1-1: The review comment is incorrect. The _namespace.monitoring value is always populated in the cozystack-values Secret.

When a Kubernetes application is deployed, the kubernetes HelmRelease uses valuesFrom: [{kind: Secret, name: cozystack-values}], which injects the Secret's values into the template context. The Secret definition in packages/core/platform/templates/apps.yaml (lines 73-78) always includes:

_namespace:
  etcd: tenant-root
  monitoring: tenant-root
  ingress: tenant-root
  seaweedfs: tenant-root

Therefore, .Values._namespace.monitoring is guaranteed to be tenant-root, and the URLs will render correctly as http://vminsert-shortterm.tenant-root.svc:8480/insert/0/prometheus and http://vlogs-generic.tenant-root.svc:9428. No default value is needed because the field is always present in the Secret.

packages/apps/ferretdb/templates/postgres.yaml (1)

53-61: LGTM! Defensive coding for optional scheduling constraints.

The conditional logic properly handles the optional .Values._cluster.scheduling configuration. The code checks for existence before accessing nested values and gracefully handles missing constraints, which is the correct approach for optional configuration.

packages/apps/clickhouse/templates/chkeeper.yaml (1)

1-1: LGTM! Proper default value for cluster-domain.

The template correctly provides a default value of "cozy.local" for the cluster domain, ensuring the template renders successfully even if .Values._cluster["cluster-domain"] is not populated in the cozystack-values Secret.

packages/extra/bootbox/templates/matchbox/machines.yaml (1)

1-1: LGTM! Clean migration to values-driven configuration.

The replacement of dynamic ConfigMap/Namespace lookups with .Values._namespace.host aligns with the PR objectives. The fallback pattern $.Values.host | default $host on line 40 provides a proper user override mechanism.

Note: The YAMLlint syntax error is a false positive—this is valid Go template syntax.

Also applies to: 40-40

packages/system/keycloak/templates/db.yaml (1)

9-17: LGTM! Proper guard and safe value access.

The migration from ConfigMap-based lookup to .Values._cluster.scheduling is correct. The conditional guard and get function ensure safe access, and the constraint processing logic remains unchanged.

Note: The YAMLlint syntax error on line 10 is a false positive—this is valid Go template syntax.

packages/apps/virtual-machine/templates/_helpers.tpl (1)

77-103: LGTM! Clean refactor of node affinity configuration.

The migration from ConfigMap lookup to .Values._cluster.scheduling is implemented correctly with proper guards. The Windows VM node affinity logic remains intact, and the use of the get function ensures safe value extraction.

packages/extra/monitoring/templates/alerta/alerta.yaml (1)

1-3: LGTM! Consolidated configuration sources.

The migration consolidates three separate lookups (issuerType, ingress, host) into direct .Values._cluster and .Values._namespace references. The default value for issuerType is appropriate, and the fallback patterns throughout the template (e.g., lines 128, 182, 185) allow proper user overrides.

Note: The YAMLlint syntax error is a false positive—this is valid Go template syntax.

packages/extra/monitoring/templates/grafana/db.yaml (1)

9-17: LGTM! Consistent scheduling configuration migration.

The replacement of ConfigMap-based topology spread constraints with .Values._cluster.scheduling follows the same correct pattern used in other database templates (e.g., keycloak/db.yaml). The guard and safe access ensure robust value handling.

Note: The YAMLlint syntax error on line 10 is a false positive—this is valid Go template syntax.

packages/extra/monitoring/templates/alerta/alerta-db.yaml (1)

8-16: LGTM!

The migration from ConfigMap lookup to .Values._cluster.scheduling is correctly implemented. The nested conditional properly guards against nil values before accessing the globalAppTopologySpreadConstraints key.

Note: The YAMLlint error on line 9 is a false positive—Helm template directives using {{- for whitespace control are valid syntax.

packages/system/cozystack-api/templates/api-ingress.yaml (1)

1-3: LGTM with a note on consistency.

The migration to .Values._cluster is correctly implemented. Lines 2-3 have appropriate defaults, but line 1 for root-host does not. This is acceptable since root-host is a required platform configuration, but for defensive consistency you could add | default "" to line 1 as well.

packages/apps/kubernetes/templates/cluster.yaml (2)

1-3: LGTM!

The migration from namespace annotations to .Values._namespace for etcd, ingress, and host is correctly implemented.


33-41: LGTM!

The scheduling constraint logic correctly checks for .Values._cluster.scheduling existence before accessing globalAppTopologySpreadConstraints. This is consistent with the pattern used across other templates in this PR.

packages/system/kubevirt/templates/vm-exportproxy-ingress.yaml (1)

1-3: LGTM!

The migration pattern is consistent with other ingress templates in this PR. The root-host value is appropriately sourced from .Values._cluster.

packages/system/kubevirt-cdi/templates/cdi-uploadproxy-ingress.yaml (1)

1-3: LGTM!

The migration to .Values._cluster is consistent with other ingress templates. The pattern correctly handles optional expose-services and expose-ingress with appropriate defaults.

pkg/registry/apps/application/rest.go (4)

151-154: LGTM!

The validation in Create() correctly rejects values containing reserved keys (starting with _) before proceeding with HelmRelease creation. This prevents users from accidentally overwriting internal configuration injected via valuesFrom.


450-453: LGTM!

Consistent validation in Update() path, preventing reserved key injection during updates.


904-922: LGTM!

The filtering of internal keys during HelmRelease-to-Application conversion ensures that injected system values (like _cluster and _namespace) are not exposed in the Application spec returned to users.


989-994: LGTM with a note on Secret dependency.

The ValuesFrom reference to cozystack-values Secret is correctly added. Since Optional is not set (defaults to false), HelmRelease reconciliation requires the Secret to exist in the target namespace. This is guaranteed by the platform and tenant chart architecture: the platform charts create this Secret in the tenant-root and platform namespaces (via packages/core/platform/templates/namespaces.yaml), while the tenant chart creates it in each tenant namespace (via packages/apps/tenant/templates/namespace.yaml).

packages/core/platform/templates/apps.yaml (4)

2-4: LGTM: ConfigMap lookups for Secret population.

These lookups are appropriate here as the platform chart is responsible for aggregating cluster configuration into the cozystack-values Secret that child charts will consume via valuesFrom.


7-19: LGTM: Defensive defaults pattern.

The combination of $clusterDefaults with mergeOverwrite and | default dict ensures all required keys exist with sensible fallback values, preventing template errors from missing configuration.


50-78: LGTM: Secret structure aligns with valuesFrom architecture.

The Secret correctly aggregates cluster and namespace configuration into _cluster and _namespace sections that will be consumed by HelmReleases via valuesFrom. The reconcile.fluxcd.io/watch: Enabled label ensures FluxCD watches for changes.


107-109: LGTM: Correct valuesFrom implementation.

The valuesFrom block correctly references the cozystack-values Secret, enabling FluxCD to populate .Values._cluster and .Values._namespace in the tenant-root HelmRelease.

packages/library/cozy-lib/templates/_cozyconfig.tpl (5)

1-12: LGTM: Well-documented helper with safe defaults.

The helper correctly uses index for hyphenated keys and | default "" provides a safe fallback when the key is missing or .Values._cluster is nil.


18-52: LGTM: Consistent helper pattern across cluster configuration accessors.

All helpers follow the same safe pattern with index for hyphenated keys and empty string defaults.


59-74: LGTM: YAML helpers with appropriate existence checks.

The scheduling and branding helpers correctly check for existence before rendering YAML, preventing empty output when these optional configurations are not present.


85-119: LGTM: Namespace configuration helpers follow consistent pattern.

The namespace-scoped helpers correctly read from .Values._namespace and provide safe defaults, aligning with the Secret structure defined in the platform chart.


125-129: LGTM: Backward compatibility preserved during migration.

The legacy loadCozyConfig helper correctly redirects to .Values._cluster, enabling gradual migration of templates while maintaining compatibility with existing code.

packages/core/platform/templates/helmreleases.yaml (1)

86-88: LGTM: Consistent valuesFrom implementation for system releases.

The valuesFrom block correctly enables all system HelmReleases to consume cluster and namespace configuration from the cozystack-values Secret, consistent with the PR's architectural goals.

packages/extra/seaweedfs/templates/ingress.yaml (1)

1-2: LGTM: Replaced lookups with values-based configuration.

The migration from runtime lookups to .Values._namespace access aligns with the PR's architectural shift to values-driven configuration.

packages/system/dashboard/templates/gatekeeper.yaml (1)

1-2: No action required — dashboard HelmRelease already has valuesFrom configured.

The dashboard chart's reliance on .Values._cluster is properly supported. The dashboard HelmRelease is generated by packages/core/platform/templates/helmreleases.yaml (not located in dashboard templates), and automatically includes valuesFrom: [{kind: Secret, name: cozystack-values}]. The cozystack-values Secret is created in each namespace by packages/core/platform/templates/namespaces.yaml and contains the _cluster configuration.

packages/apps/tenant/templates/ingress.yaml (1)

34-37: LGTM! valuesFrom mechanism correctly implemented.

The addition of the valuesFrom block referencing the cozystack-values Secret aligns with the PR's objective to replace Helm lookup functions with FluxCD valuesFrom for configuration propagation.

packages/apps/bucket/templates/helmrelease.yaml (1)

24-26: LGTM! valuesFrom configuration is correct.

The valuesFrom block is properly configured to source values from the cozystack-values Secret, consistent with the PR's architectural changes.

packages/apps/vpn/templates/secret.yaml (1)

1-1: LGTM! Migration from namespace annotation to values-based lookup.

The change correctly replaces the namespace annotation lookup with .Values._namespace.host, aligning with the PR's shift to values-driven configuration. The usage on line 66 appropriately allows override via .Values.host while falling back to the namespace host.

Note: The YAMLlint syntax error is a false positive—it doesn't recognize Helm template syntax.

packages/extra/ingress/templates/nginx-ingress.yaml (1)

1-2: LGTM! ConfigMap lookup replacement and valuesFrom addition are correct.

The changes successfully migrate from ConfigMap-based lookups to .Values._cluster access with appropriate defaults:

  • expose-ingress defaults to "tenant-root"
  • expose-external-ips defaults to empty string

The valuesFrom block ensures the cozystack-values Secret populates these values. This aligns perfectly with the PR's architectural shift to values-driven configuration.

Note: The YAMLlint syntax error is a false positive—it doesn't understand Helm template syntax.

Also applies to: 26-28

packages/system/dashboard/templates/ingress.yaml (1)

1-4: LGTM! Clean migration from ConfigMap lookup to values-based configuration.

The migration from runtime ConfigMap lookups to .Values._cluster is correct and maintains the same default values as before. The configuration will now be properly injected via the valuesFrom mechanism.

packages/extra/bootbox/templates/matchbox/ingress.yaml (1)

1-3: LGTM! Proper use of both cluster and namespace values.

The migration correctly uses .Values._cluster for cluster-wide configuration (issuerType) and .Values._namespace for namespace-specific settings (ingress, host). The conditional logic for the cloudflare issuer type is properly preserved.

packages/system/dashboard/templates/configmap.yaml (1)

1-24: LGTM! Clean branding configuration migration.

The migration from ConfigMap-based branding lookup to .Values._cluster.branding is correct. The template properly accesses individual branding fields with appropriate fallbacks to default values.

packages/extra/info/templates/kubeconfig.yaml (2)

1-1: LGTM! Configuration values properly migrated.

The migration of host, API server endpoint, management kubeconfig endpoint, and kube-root-ca from runtime lookups to .Values._cluster and .Values._namespace is correct and complete.

Also applies to: 5-6, 11-11


2-2: Clarify architectural intent: Is cross-namespace k8s-client lookup still required?

The k8s-client Secret lookup on line 2 is part of a consistent pattern across the codebase (also used in keycloak-configure and dashboard templates), with no current migration to valuesFrom. However, note that this lookup accesses the secret in the "cozy-keycloak" namespace, while keycloak-configure creates the k8s-client Secret in its own release namespace.

Since force-reconcile controllers are being removed, confirm whether this runtime lookup remains the intended mechanism for accessing the OIDC client credential, or if a values-based approach is now preferred for consistency with other secret handling.

packages/core/platform/templates/namespaces.yaml (1)

5-17: Good use of defaults pattern with mergeOverwrite.

The $clusterDefaults dictionary provides sensible defaults for all required keys, ensuring consuming templates don't fail when optional config values are missing. The mergeOverwrite correctly applies user config on top of defaults.

packages/apps/nats/templates/nats.yaml (2)

1-1: Correctly migrated to Values-based cluster-domain access.

The change from ConfigMap lookup to .Values._cluster["cluster-domain"] aligns with the PR's objective. The default "cozy.local" is consistent with the $clusterDefaults defined in the platform chart.

Note: The YAMLlint error is a false positive — this is a Helm template file where {{- is valid templating syntax, not raw YAML.


55-57: valuesFrom correctly references cozystack-values Secret.

The valuesFrom block properly sources values from the namespace-scoped Secret, enabling FluxCD to inject _cluster (and _namespace where applicable) into the HelmRelease values.

packages/apps/tenant/templates/namespace.yaml (2)

8-40: Well-structured computed values for reuse across Namespace and Secret.

The service reference computation correctly inherits from parent namespace and overrides when the tenant explicitly enables a service (e.g., if .Values.etcd). The host derivation logic appropriately extracts the last segment of the tenant name for subdomain construction.


55-60: Network policy labels enable cross-namespace access control.

Adding namespace.cozystack.io/* labels allows NetworkPolicies to select namespaces based on their service references (etcd, ingress, monitoring, seaweedfs, host). This is a clean approach for multi-tenant network isolation.

Comment on lines +55 to +75
---
apiVersion: v1
kind: Secret
metadata:
name: cozystack-values
namespace: {{ $namespace }}
labels:
reconcile.fluxcd.io/watch: Enabled
type: Opaque
stringData:
values.yaml: |
_cluster:
{{- $clusterConfig | toYaml | nindent 6 }}
{{- with $cozystackBranding.data }}
branding:
{{- . | toYaml | nindent 8 }}
{{- end }}
{{- with $cozystackScheduling.data }}
scheduling:
{{- . | toYaml | nindent 8 }}
{{- end }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all references to _namespace in relevant directories
rg -n --type yaml '_namespace\.' packages/system/ packages/core/ -g '!*.md' 2>/dev/null | head -50

Repository: cozystack/cozystack

Length of output: 244


🏁 Script executed:

#!/bin/bash
# Find the tenant template mentioned in the review
find . -type f -name "*.yaml" -path "*/templates/*" | xargs grep -l "tenant" | head -20

Repository: cozystack/cozystack

Length of output: 1084


🏁 Script executed:

#!/bin/bash
# Look at the namespaces.yaml file to understand context
wc -l packages/core/platform/templates/namespaces.yaml

Repository: cozystack/cozystack

Length of output: 114


🏁 Script executed:

#!/bin/bash
# Look at the tenant template to compare structure
cat packages/apps/tenant/templates/tenant.yaml | head -100

Repository: cozystack/cozystack

Length of output: 2359


🏁 Script executed:

#!/bin/bash
# Check the bucket template that references _namespace
cat packages/system/bucket/templates/ingress.yaml

Repository: cozystack/cozystack

Length of output: 1292


🏁 Script executed:

#!/bin/bash
# Find more references to _namespace in system packages
rg -n '_namespace\.' packages/system/ -g '!*.md' -A 2

Repository: cozystack/cozystack

Length of output: 423


🏁 Script executed:

#!/bin/bash
# Check if there are any system HelmReleases that use the cozystack-values Secret
rg -n "cozystack-values" packages/core/ packages/system/ -g '!*.md'

Repository: cozystack/cozystack

Length of output: 367


🏁 Script executed:

#!/bin/bash
# Check the namespace.yaml in tenant (mentioned as having both _cluster and _namespace)
cat packages/apps/tenant/templates/namespace.yaml

Repository: cozystack/cozystack

Length of output: 2838


🏁 Script executed:

#!/bin/bash
# Look at more references to _namespace to see scope of the issue
rg -n '_namespace\.' packages/ -g '!*.md' --type yaml

Repository: cozystack/cozystack

Length of output: 2378


🏁 Script executed:

#!/bin/bash
# Check how cozystack-values is actually used in helmreleases.yaml
sed -n '85,95p' packages/core/platform/templates/helmreleases.yaml

Repository: cozystack/cozystack

Length of output: 327


🏁 Script executed:

#!/bin/bash
# Look for any defaults or conditional handling of _namespace
rg -n '_namespace' packages/system/ -g '!*.md' -A 3 -B 1

Repository: cozystack/cozystack

Length of output: 50376


🏁 Script executed:

#!/bin/bash
# Check what HelmReleases in platform use the cozystack-values Secret
sed -n '80,115p' packages/core/platform/templates/helmreleases.yaml

Repository: cozystack/cozystack

Length of output: 527


🏁 Script executed:

#!/bin/bash
# Check if system templates that require _namespace are actually installed in platform namespaces
rg -n "bucket" packages/core/platform/templates/ -g '!*.md'

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Look at what system packages are deployed to platform namespaces via apps.yaml
cat packages/core/platform/templates/apps.yaml | head -80

Repository: cozystack/cozystack

Length of output: 2762


🏁 Script executed:

#!/bin/bash
# Check if system/bucket is deployed to platform namespaces
rg -n "bucket" packages/core/platform/templates/apps.yaml -A 3 -B 3

Repository: cozystack/cozystack

Length of output: 45


🏁 Script executed:

#!/bin/bash
# Look at the full platform apps.yaml to see what system packages are deployed
cat packages/core/platform/templates/apps.yaml | tail -100

Repository: cozystack/cozystack

Length of output: 2789


🏁 Script executed:

#!/bin/bash
# Check the bundle configuration to see what gets deployed to platform
cat packages/core/platform/templates/bundles/default.yaml 2>/dev/null || cat packages/core/platform/templates/bundles/*.yaml | head -100

Repository: cozystack/cozystack

Length of output: 149


🏁 Script executed:

#!/bin/bash
# Check if the platform namespace Secret is actually missing _namespace by examining the full Secret definition
sed -n '54,76p' packages/core/platform/templates/namespaces.yaml

Repository: cozystack/cozystack

Length of output: 579


🏁 Script executed:

#!/bin/bash
# Confirm what HelmReleases are deployed to platform namespaces and verify they use cozystack-values
rg -n "namespace: {{ \$namespace }}" packages/core/platform/templates/helmreleases.yaml -A 20 | head -60

Repository: cozystack/cozystack

Length of output: 184


🏁 Script executed:

#!/bin/bash
# Verify by looking at what comes after the _cluster block in platform Secret
sed -n '54,75p' packages/core/platform/templates/namespaces.yaml | cat -A

Repository: cozystack/cozystack

Length of output: 590


Ensure platform namespace HelmReleases gracefully handle missing _namespace values.

The Secret cozystack-values in platform namespaces contains only _cluster configuration, differing from the tenant template which includes both _cluster and _namespace blocks. System packages deployed to platform namespaces that reference .Values._namespace.* fields (e.g., host, etcd, ingress, seaweedfs) will receive nil values. While this omission may be intentional for system infrastructure, all consuming HelmReleases should either provide appropriate defaults or verify their templates can safely handle undefined _namespace values.

🤖 Prompt for AI Agents
In @packages/core/platform/templates/namespaces.yaml around lines 55-75, The
Secret "cozystack-values" only defines the _cluster block and omits _namespace,
which causes HelmReleases consuming .Values._namespace.* (e.g., host, etcd,
ingress, seaweedfs) to get nil; update the template producing the Secret
(cozystack-values) or downstream HelmRelease templates to handle missing
_namespace: either add a safe default _namespace block alongside _cluster in the
cozystack-values Secret generation (mirroring tenant template) or modify
consuming charts/templates to use defaulting functions or conditional checks
when accessing .Values._namespace (e.g., guard expressions or helm default
function around .Values._namespace.host/etcd/ingress/seaweedfs) so undefined
values do not cause nil derefs.

Comment on lines +1 to +2
{{- $host := .Values._namespace.host }}
{{- $ingress := .Values._namespace.ingress }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add defaults for host and ingress values to prevent template failure.

Lines 1-2 access .Values._namespace.host and .Values._namespace.ingress without defaults, while line 3 provides a default for clusterissuer. If these values are missing from the cozystack-values Secret, template rendering will fail when referenced at lines 17, 21, 24, and 27.

🔎 Proposed fix
-{{- $host := .Values._namespace.host }}
-{{- $ingress := .Values._namespace.ingress }}
+{{- $host := .Values._namespace.host | required ".Values._namespace.host is required for ingress configuration" }}
+{{- $ingress := .Values._namespace.ingress | required ".Values._namespace.ingress is required for ingress configuration" }}

Alternatively, if sensible defaults exist:

-{{- $host := .Values._namespace.host }}
-{{- $ingress := .Values._namespace.ingress }}
+{{- $host := .Values._namespace.host | default "example.local" }}
+{{- $ingress := .Values._namespace.ingress | default "nginx" }}
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 1-1: syntax error: expected the node content, but found '-'

(syntax)

🤖 Prompt for AI Agents
In @packages/system/bucket/templates/ingress.yaml around lines 1-2, The template
currently grabs .Values._namespace.host and .Values._namespace.ingress without
defaults causing render failures when those keys are absent; change the variable
assignments to use Helm's default function (e.g. set $host := default ""
.Values._namespace.host and set $ingress := default false
.Values._namespace.ingress or another sensible default like an empty map/string)
so references to $host and $ingress (and the existing clusterissuer logic) won't
break if the Secret omits those keys; update any downstream logic that expects a
non-empty value to handle the chosen default.

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Jan 5, 2026
@kvaps kvaps merged commit 5f36396 into cozystack:main Jan 5, 2026
24 checks passed
kvaps added a commit that referenced this pull request Jan 8, 2026
## What this PR does

Replaces Helm lookup functions with FluxCD valuesFrom mechanism for
passing configuration to HelmReleases. This provides cleaner config
propagation and eliminates the need for force reconcile controllers.

### Changes:

**Platform/Tenant charts:**
- Add Secret `cozystack-values` creation in platform chart (for
tenant-root and system namespaces)
- Add Secret `cozystack-values` creation in tenant chart (for child
namespaces)

**cozystack-api:**
- Add `valuesFrom` references to HelmRelease when creating applications
- Filter keys starting with `_` when returning Application specs
- Validate that user values don't contain `_` prefixed keys

**cozystack-controller:**
- Add validation that HelmRelease contains correct valuesFrom
configuration
- Remove `CozystackConfigReconciler` (no longer needed)
- Remove `TenantHelmReconciler` (no longer needed)

**Helm charts (40+ files):**
- Add helper templates in cozy-lib for `_cluster`/`_namespace` access
- Replace ConfigMap lookups with `.Values._cluster.*`
- Replace Namespace annotation lookups with `.Values._namespace.*`

### Architecture:

```
Secret cozystack-values (in each namespace)
├── _cluster: YAML with data from ConfigMaps (cozystack, cozystack-branding, cozystack-scheduling)
└── _namespace: YAML with namespace service references (etcd, host, ingress, monitoring, seaweedfs)

HelmRelease
└── spec.valuesFrom:
    ├── Secret/cozystack-values → _namespace → .Values._namespace
    └── Secret/cozystack-values → _cluster → .Values._cluster
```

### Release note

```release-note
[platform] Replace Helm lookup functions with FluxCD valuesFrom mechanism for configuration propagation
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Helm releases and namespaces now source centralized cluster/namespace
configuration via a new secret (cozystack-values), and many templates
read values from chart-provided _cluster/_namespace entries.

* **Bug Fixes**
* API now rejects application specs containing reserved keys prefixed
with "_" to prevent invalid configurations.

* **Refactor**
* Two background reconciler controllers were removed from startup,
simplifying controller initialization.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
kvaps added a commit that referenced this pull request Jan 8, 2026
## What this PR does

Replaces Helm lookup functions with FluxCD valuesFrom mechanism for
passing configuration to HelmReleases. This provides cleaner config
propagation and eliminates the need for force reconcile controllers.

### Changes:

**Platform/Tenant charts:**
- Add Secret `cozystack-values` creation in platform chart (for
tenant-root and system namespaces)
- Add Secret `cozystack-values` creation in tenant chart (for child
namespaces)

**cozystack-api:**
- Add `valuesFrom` references to HelmRelease when creating applications
- Filter keys starting with `_` when returning Application specs
- Validate that user values don't contain `_` prefixed keys

**cozystack-controller:**
- Add validation that HelmRelease contains correct valuesFrom
configuration
- Remove `CozystackConfigReconciler` (no longer needed)
- Remove `TenantHelmReconciler` (no longer needed)

**Helm charts (40+ files):**
- Add helper templates in cozy-lib for `_cluster`/`_namespace` access
- Replace ConfigMap lookups with `.Values._cluster.*`
- Replace Namespace annotation lookups with `.Values._namespace.*`

### Architecture:

```
Secret cozystack-values (in each namespace)
├── _cluster: YAML with data from ConfigMaps (cozystack, cozystack-branding, cozystack-scheduling)
└── _namespace: YAML with namespace service references (etcd, host, ingress, monitoring, seaweedfs)

HelmRelease
└── spec.valuesFrom:
    ├── Secret/cozystack-values → _namespace → .Values._namespace
    └── Secret/cozystack-values → _cluster → .Values._cluster
```

### Release note

```release-note
[platform] Replace Helm lookup functions with FluxCD valuesFrom mechanism for configuration propagation
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Helm releases and namespaces now source centralized cluster/namespace
configuration via a new secret (cozystack-values), and many templates
read values from chart-provided _cluster/_namespace entries.

* **Bug Fixes**
* API now rejects application specs containing reserved keys prefixed
with "_" to prevent invalid configurations.

* **Refactor**
* Two background reconciler controllers were removed from startup,
simplifying controller initialization.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
kvaps added a commit that referenced this pull request Jan 9, 2026
## What this PR does

Replaces Helm lookup functions with FluxCD valuesFrom mechanism for
passing configuration to HelmReleases. This provides cleaner config
propagation and eliminates the need for force reconcile controllers.

### Changes:

**Platform/Tenant charts:**
- Add Secret `cozystack-values` creation in platform chart (for
tenant-root and system namespaces)
- Add Secret `cozystack-values` creation in tenant chart (for child
namespaces)

**cozystack-api:**
- Add `valuesFrom` references to HelmRelease when creating applications
- Filter keys starting with `_` when returning Application specs
- Validate that user values don't contain `_` prefixed keys

**cozystack-controller:**
- Add validation that HelmRelease contains correct valuesFrom
configuration
- Remove `CozystackConfigReconciler` (no longer needed)
- Remove `TenantHelmReconciler` (no longer needed)

**Helm charts (40+ files):**
- Add helper templates in cozy-lib for `_cluster`/`_namespace` access
- Replace ConfigMap lookups with `.Values._cluster.*`
- Replace Namespace annotation lookups with `.Values._namespace.*`

### Architecture:

```
Secret cozystack-values (in each namespace)
├── _cluster: YAML with data from ConfigMaps (cozystack, cozystack-branding, cozystack-scheduling)
└── _namespace: YAML with namespace service references (etcd, host, ingress, monitoring, seaweedfs)

HelmRelease
└── spec.valuesFrom:
    ├── Secret/cozystack-values → _namespace → .Values._namespace
    └── Secret/cozystack-values → _cluster → .Values._cluster
```

### Release note

```release-note
[platform] Replace Helm lookup functions with FluxCD valuesFrom mechanism for configuration propagation
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Helm releases and namespaces now source centralized cluster/namespace
configuration via a new secret (cozystack-values), and many templates
read values from chart-provided _cluster/_namespace entries.

* **Bug Fixes**
* API now rejects application specs containing reserved keys prefixed
with "_" to prevent invalid configurations.

* **Refactor**
* Two background reconciler controllers were removed from startup,
simplifying controller initialization.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants