Skip to content

[platform] add hr reconciler - #870

Merged
klinch0 merged 1 commit into
mainfrom
(platform)--add-hr-reconciler
May 5, 2025
Merged

[platform] add hr reconciler#870
klinch0 merged 1 commit into
mainfrom
(platform)--add-hr-reconciler

Conversation

@klinch0

@klinch0 klinch0 commented Apr 24, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Introduced a new controller to synchronize tenant HelmReleases and propagate configuration changes.
    • Added dynamic host value overrides in multiple Helm templates by conditionally retrieving values from the "tenant-root" HelmRelease.
    • Updated RBAC permissions to allow management of HelmRelease resources.
  • Improvements

    • Added support for Helm v2 API integration.
    • Enhanced HelmRelease reconciliation logic and configuration propagation for tenant environments.
  • Bug Fixes

    • Fixed periodic reconciliation for the "tenant-root" HelmRelease by setting its interval to zero.
  • Version Updates

    • Incremented version numbers for the "info" and "ingress" packages.
  • Chores

    • Updated version mappings and commit references.
    • Improved .gitignore to exclude the .vscode directory.

@coderabbitai

coderabbitai Bot commented Apr 24, 2025

Copy link
Copy Markdown
Contributor

"""

Walkthrough

This update introduces a new TenantHelmReconciler controller to synchronize tenant HelmRelease resources based on the root tenant's configuration. The controller watches HelmReleases, propagates configuration digests, and annotates namespaces as needed. The main controller setup is extended to include the new reconciler, and the RBAC policy is updated to grant necessary permissions for managing HelmReleases. Several Helm templates are modified to dynamically source the host value from the root HelmRelease if available. Package version metadata and references are incremented, and the .gitignore is updated to exclude .vscode.

Changes

Files/Paths Change Summary
.gitignore Added .vscode to ignore list and appended a newline.
cmd/cozystack-controller/main.go Imported Helm v2 API, registered its scheme, and set up the new TenantHelmReconciler controller with the manager.
internal/controller/tenant_helm_reconciler.go Introduced TenantHelmReconciler for syncing tenant HelmReleases and annotating namespaces based on configuration digests.
packages/core/platform/templates/apps.yaml Changed tenant-root HelmRelease spec.interval from "1m" to "0s".
packages/extra/info/Chart.yaml
packages/extra/ingress/Chart.yaml
Incremented chart version numbers (info to 1.0.1, ingress to 1.5.1).
packages/extra/info/templates/kubeconfig.yaml
packages/extra/ingress/templates/dashboard.yaml
packages/system/keycloak-configure/templates/configure-kk.yaml
packages/system/keycloak/templates/ingress.yaml
packages/system/keycloak/templates/sts.yaml
Added logic to conditionally override $host by retrieving it from the root HelmRelease if available.
packages/extra/versions_map Updated commit hashes for previous package versions and added new entries for updated versions.
packages/system/cozystack-controller/templates/rbac.yaml Extended ClusterRole to allow managing HelmRelease resources in the helm.toolkit.fluxcd.io API group.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Controller Manager
    participant TenantHelmReconciler
    participant Kubernetes API
    participant HelmRelease (tenant-root)
    participant Child Namespace

    Controller Manager->>TenantHelmReconciler: Start reconciliation loop
    TenantHelmReconciler->>Kubernetes API: List HelmReleases (filter: name starts with "tenant-")
    loop For each HelmRelease
        TenantHelmReconciler->>HelmRelease (tenant-root): Check status and conditions
        alt Is "tenant-root" in "tenant-root" namespace
            TenantHelmReconciler->>Kubernetes API: Annotate "tenant-root" namespace with host value
        end
        TenantHelmReconciler->>Child Namespace: List HelmReleases in child namespace
        TenantHelmReconciler->>Child Namespace: Patch HelmRelease if digest differs
    end
Loading

Possibly related PRs

Suggested labels

ok-to-test

Poem

🐇
A hop and a patch, a new controller in play,
HelmReleases now sync in a magical way.
With digests and hosts, the tenants align,
RBAC permissions—now everything’s fine!
Templates look up, for the host at the root,
This bunny’s delighted—deploy and reboot!
🌱
"""


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d489421 and f61a781.

📒 Files selected for processing (13)
  • .gitignore (2 hunks)
  • cmd/cozystack-controller/main.go (3 hunks)
  • internal/controller/tenant_helm_reconciler.go (1 hunks)
  • packages/core/platform/templates/apps.yaml (2 hunks)
  • packages/extra/info/Chart.yaml (1 hunks)
  • packages/extra/info/templates/kubeconfig.yaml (1 hunks)
  • packages/extra/ingress/Chart.yaml (1 hunks)
  • packages/extra/ingress/templates/dashboard.yaml (1 hunks)
  • packages/extra/versions_map (1 hunks)
  • packages/system/cozystack-controller/templates/rbac.yaml (1 hunks)
  • packages/system/keycloak-configure/templates/configure-kk.yaml (1 hunks)
  • packages/system/keycloak/templates/ingress.yaml (1 hunks)
  • packages/system/keycloak/templates/sts.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/extra/info/Chart.yaml
  • packages/core/platform/templates/apps.yaml
  • packages/extra/ingress/Chart.yaml
  • packages/system/cozystack-controller/templates/rbac.yaml
  • packages/extra/ingress/templates/dashboard.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/extra/versions_map
  • packages/system/keycloak/templates/sts.yaml
  • packages/extra/info/templates/kubeconfig.yaml
  • cmd/cozystack-controller/main.go
  • internal/controller/tenant_helm_reconciler.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build and Test
✨ 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Comment thread cmd/cozystack-controller/main.go Outdated
@klinch0
klinch0 force-pushed the (platform)--add-hr-reconciler branch 3 times, most recently from 2f028da to 799a59e Compare April 30, 2025 12:11
@klinch0
klinch0 marked this pull request as ready for review April 30, 2025 12:12

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (6)
packages/system/keycloak/templates/ingress.yaml (1)

8-15: DRY up tenant-root lookup across templates.
This tenant-root lookup block is repeated in multiple charts. Consider extracting it into a helper function in _helpers.tpl (e.g., {{ include "cozystack.tenantRootHost" . }}) to reduce duplication and improve maintainability.

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

15-22: Extract tenant-root lookup into a helper.
This snippet recurs across multiple templates. Move it into a function in _helpers.tpl (e.g., tenantRootHost) and call it in each chart to keep templates DRY.

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

10-17: Consolidate repeated tenant-root lookup.
The same tenant-root lookup logic appears in multiple templates. Extract it into a shared helper in _helpers.tpl to improve maintainability and reduce duplication.

cmd/cozystack-controller/main.go (1)

193-199: Incorrect controller name in log message

setupLog.Error(err, "unable to create controller", "controller", "Workload") will mis-lead operators when the TenantHelmReconciler fails because the structured field still says "Workload".
Use the actual controller name to avoid confusion during troubleshooting.

-		setupLog.Error(err, "unable to create controller", "controller", "Workload")
+		setupLog.Error(err, "unable to create controller", "controller", "TenantHelm")
internal/controller/tenant_helm_reconciler.go (2)

67-70: Incorrect field in log: namespace is set to HelmRelease name

logger.Error(err, ... "namespace", hr.Name) passes the name instead of the namespace, making logs misleading.

-	logger.Error(err, "unable to list HelmReleases in namespace", "namespace", hr.Name)
+	logger.Error(err, "unable to list HelmReleases in namespace", "namespace", childNamespace)

127-152: Namespace update should use patch & incoming context

annotateTenantRootNs fetches and Updates the Namespace with a full object write.
Using Patch avoids clobbering concurrent updates and honours server-side apply semantics; also context.TODO() loses cancellation.

Consider:

-	if err := c.Get(context.TODO(), client.ObjectKey{Name: "tenant-root"}, &ns); err != nil {
+	if err := c.Get(ctx, client.ObjectKey{Name: "tenant-root"}, &ns); err != nil {
...
-	if err := c.Update(context.TODO(), &ns); err != nil {
+	if err := c.Patch(ctx, &ns, client.MergeFrom(original)); err != nil {

(Where ctx is passed down and original is a deep copy made right after Get.)

This reduces race risk with other controllers or kubectl edits.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c482289 and 799a59e.

📒 Files selected for processing (13)
  • .gitignore (2 hunks)
  • cmd/cozystack-controller/main.go (3 hunks)
  • internal/controller/tenant_helm_reconciler.go (1 hunks)
  • packages/core/platform/templates/apps.yaml (1 hunks)
  • packages/extra/info/Chart.yaml (1 hunks)
  • packages/extra/info/templates/kubeconfig.yaml (1 hunks)
  • packages/extra/ingress/Chart.yaml (1 hunks)
  • packages/extra/ingress/templates/dashboard.yaml (1 hunks)
  • packages/extra/versions_map (1 hunks)
  • packages/system/cozystack-controller/templates/rbac.yaml (1 hunks)
  • packages/system/keycloak-configure/templates/configure-kk.yaml (1 hunks)
  • packages/system/keycloak/templates/ingress.yaml (1 hunks)
  • packages/system/keycloak/templates/sts.yaml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build and Test
🔇 Additional comments (7)
.gitignore (2)

4-4: Ignore VSCode workspace settings
Adding .vscode to the ignore list aligns with existing IDE-specific ignores (.idea) and prevents committing editor configurations.


79-79: Enhance .DS_Store ignore pattern
Using **/.DS_Store ensures macOS metadata files are ignored in nested directories as well, improving repository cleanliness.

packages/extra/info/Chart.yaml (1)

6-6: Bump chart version for info package
The version field has been correctly incremented to 1.0.1 to reflect the new template logic.

packages/extra/ingress/Chart.yaml (1)

6-6: Bump chart version for ingress package
The version field has been correctly updated to 1.5.1 to coordinate with the tenant HelmRelease host override changes.

packages/extra/versions_map (2)

14-15: Update info package commit references
Locked info 1.0.0 to 93bdf411 and added info 1.0.1 pointing at HEAD to match the Chart version bump.


21-22: Update ingress package commit references
Locked ingress 1.5.0 to 93bdf411 and added ingress 1.5.1 pointing at HEAD in line with the chart version increment.

packages/system/cozystack-controller/templates/rbac.yaml (1)

12-14: Approve RBAC addition for HelmRelease resources.
The new rule correctly grants get, list, watch, patch, and update verbs on helmreleases in the helm.toolkit.fluxcd.io API group, which is required for the TenantHelmReconciler to manage HelmRelease resources.

Comment thread packages/core/platform/templates/apps.yaml Outdated
Comment thread packages/extra/ingress/templates/dashboard.yaml Outdated
Comment thread packages/system/keycloak/templates/ingress.yaml Outdated
Comment thread packages/extra/info/templates/kubeconfig.yaml Outdated
Comment on lines +10 to +17
{{- $tenantRoot := list }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}

@coderabbitai coderabbitai Bot Apr 30, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix initialization of $tenantRoot to avoid runtime errors.
Initialising $tenantRoot with list means the and guard may still evaluate truthy for an empty list and then error on .spec. Replace with:

- {{- $tenantRoot := list }}
+ {{- $tenantRoot := nil }}
📝 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
{{- $tenantRoot := list }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}
{{- $tenantRoot := nil }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
{{- $tenantRoot := list }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot := lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- end }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Timofei Larkin (@lllamnyp) Your suggestion is excellent and actually improves upon my original recommendation! By moving the variable declaration inside the API version check and combining the conditionals, you've:

  1. Eliminated the potential runtime error from an empty list
  2. Improved variable scoping (only declaring where needed)
  3. Removed the unnecessary empty else clause
  4. Created more concise and readable code

This approach is more idiomatic for Go templates and produces cleaner code overall. Nice improvement!

Comment on lines +7 to +14
{{- $tenantRoot := list }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Possible template panic when CRD is absent

When the HelmRelease CRD is not installed, $tenantRoot remains a non-nil list, making
$tenantRoot.spec illegal and the template renders with:

template: ... invalid type for index: slice

A minimal, defensive rewrite prevents the panic and removes the now-useless else block:

-{{- $tenantRoot := list }}
-{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
-{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
-{{- end }}
-{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
-{{- $host = $tenantRoot.spec.values.host }}
-{{- else }}
-{{- end }}
+{{- $tenantRoot := dict }}
+{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
+  {{- $tenantRoot = (lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root") | default dict }}
+{{- end }}
+{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
+  {{- $host = $tenantRoot.spec.values.host }}
+{{- end }}
📝 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
{{- $tenantRoot := list }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}
{{- $tenantRoot := dict }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = (lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root") | default dict }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- end }}

Comment thread internal/controller/tenant_helm_reconciler.go
Comment thread internal/controller/tenant_helm_reconciler.go Outdated
Comment thread internal/controller/tenant_helm_reconciler.go Outdated
Comment on lines +15 to +20
{{- $tenantRoot := list }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No need to initialize the variable. lookup already returns nil or the content of the resource. You could just do this:

Suggested change
{{- $tenantRoot := list }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- end }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- else }}
{{- end }}
{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }}
{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }}
{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }}
{{- $host = $tenantRoot.spec.values.host }}
{{- end }}
{{- end }}

@klinch0
klinch0 force-pushed the (platform)--add-hr-reconciler branch from 799a59e to d489421 Compare May 2, 2025 14:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (3)
internal/controller/tenant_helm_reconciler.go (3)

45-50: ⚠️ Potential issue

hr.Status.History[0] still indexed before the length check (duplicate of earlier review)

The first access at line 45 precedes the len(hr.Status.History) guard on line 49, so the panic risk reported in the previous review remains.

Suggested quick fix (move the guard before the access and drop the redundant second check):

-	if hr.Status.History[0].Status != "deployed" {
-		return ctrl.Result{}, nil
-	}
-
-	if len(hr.Status.History) == 0 {
+	if len(hr.Status.History) == 0 {
 		logger.Info("no history in HelmRelease status", "name", hr.Name)
 		return ctrl.Result{}, nil
 	}
 
-	if hr.Status.History[0].Status != "deployed" {
+	if hr.Status.History[0].Status != "deployed" {
 		return ctrl.Result{}, nil
 	}

61-66: ⚠️ Potential issue

Possible nil-pointer dereference of hr.Spec.Values (duplicate of earlier review)

hr.Spec.Values is a pointer; if it’s nil, the dereference *hr.Spec.Values will panic.

-		err := annotateTenantRootNs(*hr.Spec.Values, r.Client)
+		if hr.Spec.Values == nil {
+			logger.Info("tenant-root HelmRelease has no .spec.values; skipping namespace annotation")
+		} else if err := annotateTenantRootNs(*hr.Spec.Values, r.Client); err != nil {
+			logger.Error(err, "cant annotate tenant-root ns")
+			return ctrl.Result{}, err
+		}

117-128: 🛠️ Refactor suggestion

getChildNamespace still duplicates tenant name for dedicated namespaces (duplicate of earlier review)

For a HelmRelease tenant-foo living in namespace tenant-foo, the function returns tenant-foo-foo, breaking look-ups.

-	default:
-		// 3) tenant in a dedicated namespace
-		return fmt.Sprintf("%s-%s", currentNamespace, tenantName)
+	default:
+		// 3) tenant in its own namespace – return namespace unchanged
+		return currentNamespace
🧹 Nitpick comments (2)
internal/controller/tenant_helm_reconciler.go (2)

71-73: Incorrect namespace in error log

hr.Name is logged where childNamespace (or hr.Namespace) is intended, which can mislead troubleshooting.

-	logger.Error(err, "unable to list HelmReleases in namespace", "namespace", hr.Name)
+	logger.Error(err, "unable to list HelmReleases in namespace", "namespace", childNamespace)

131-156: Use caller context instead of context.TODO() and prefer JSON unmarshal

Minor but useful clean-ups:

  1. context.TODO() discards cancellation/deadline from the Reconcile context.
  2. Since values.Raw is already JSON, json.Unmarshal avoids YAML quirks.
-func annotateTenantRootNs(values apiextensionsv1.JSON, c client.Client) error {
+func annotateTenantRootNs(ctx context.Context, values apiextensionsv1.JSON, c client.Client) error {
@@
-	if err := yaml.Unmarshal(values.Raw, &data); err != nil {
+	if err := json.Unmarshal(values.Raw, &data); err != nil {
@@
-	if err := c.Get(context.TODO(), client.ObjectKey{Name: "tenant-root"}, &ns); err != nil {
+	if err := c.Get(ctx, client.ObjectKey{Name: "tenant-root"}, &ns); err != nil {
@@
-	if err := c.Update(context.TODO(), &ns); err != nil {
+	if err := c.Update(ctx, &ns); err != nil {

Caller adjustment:

-		err := annotateTenantRootNs(*hr.Spec.Values, r.Client)
+		err := annotateTenantRootNs(ctx, *hr.Spec.Values, r.Client)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 799a59e and d489421.

📒 Files selected for processing (13)
  • .gitignore (2 hunks)
  • cmd/cozystack-controller/main.go (3 hunks)
  • internal/controller/tenant_helm_reconciler.go (1 hunks)
  • packages/core/platform/templates/apps.yaml (1 hunks)
  • packages/extra/info/Chart.yaml (1 hunks)
  • packages/extra/info/templates/kubeconfig.yaml (1 hunks)
  • packages/extra/ingress/Chart.yaml (1 hunks)
  • packages/extra/ingress/templates/dashboard.yaml (1 hunks)
  • packages/extra/versions_map (1 hunks)
  • packages/system/cozystack-controller/templates/rbac.yaml (1 hunks)
  • packages/system/keycloak-configure/templates/configure-kk.yaml (1 hunks)
  • packages/system/keycloak/templates/ingress.yaml (1 hunks)
  • packages/system/keycloak/templates/sts.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/core/platform/templates/apps.yaml
🚧 Files skipped from review as they are similar to previous changes (11)
  • packages/extra/info/Chart.yaml
  • packages/extra/ingress/templates/dashboard.yaml
  • packages/system/keycloak/templates/ingress.yaml
  • .gitignore
  • packages/system/cozystack-controller/templates/rbac.yaml
  • packages/extra/ingress/Chart.yaml
  • packages/system/keycloak-configure/templates/configure-kk.yaml
  • packages/extra/versions_map
  • cmd/cozystack-controller/main.go
  • packages/system/keycloak/templates/sts.yaml
  • packages/extra/info/templates/kubeconfig.yaml
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build and Test
🔇 Additional comments (1)
internal/controller/tenant_helm_reconciler.go (1)

41-43: ⚠️ Potential issue

Unsafe access to hr.Status.Conditions[0] without length check

hr.Status.Conditions[0] is dereferenced before verifying that len(hr.Status.Conditions) > 0. When a HelmRelease has no conditions yet (first reconcile, install error, etc.) the controller will panic.

-	if len(hr.Status.Conditions) == 0 || hr.Status.Conditions[0].Type != "Ready" {
+	if len(hr.Status.Conditions) == 0 {
+		return ctrl.Result{}, nil
+	}
+
+	cond := hr.Status.Conditions[0]
+	if cond.Type != "Ready" || cond.Status != metav1.ConditionTrue {
 		return ctrl.Result{}, nil
 	}

(The additional Status == True guard prevents premature exits while the release is progressing.)

Likely an incorrect or invalid review comment.

Comment thread internal/controller/tenant_helm_reconciler.go Outdated
Comment thread internal/controller/tenant_helm_reconciler.go
Comment thread packages/extra/info/templates/kubeconfig.yaml Outdated
Signed-off-by: kklinch0 <kklinch0@gmail.com>
@klinch0
klinch0 force-pushed the (platform)--add-hr-reconciler branch from ddfaf9c to f61a781 Compare May 5, 2025 06:27
@klinch0
klinch0 merged commit dca732c into main May 5, 2025
@klinch0
klinch0 deleted the (platform)--add-hr-reconciler branch May 5, 2025 13:41
Timofei Larkin (lllamnyp) pushed a commit that referenced this pull request May 20, 2025
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new controller to synchronize tenant HelmReleases and
propagate configuration changes.
- Added dynamic host value overrides in multiple Helm templates by
conditionally retrieving values from the "tenant-root" HelmRelease.
- Updated RBAC permissions to allow management of HelmRelease resources.

- **Improvements**
  - Added support for Helm v2 API integration.
- Enhanced HelmRelease reconciliation logic and configuration
propagation for tenant environments.

- **Bug Fixes**
- Fixed periodic reconciliation for the "tenant-root" HelmRelease by
setting its interval to zero.

- **Version Updates**
  - Incremented version numbers for the "info" and "ingress" packages.

- **Chores**
  - Updated version mappings and commit references.
  - Improved .gitignore to exclude the .vscode directory.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

(cherry picked from commit dca732c)
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants