Skip to content

[monitoring] Scope infrastructure dashboards to tenant-root only - #2197

Merged
Andrei Kvapil (kvaps) merged 1 commit into
cozystack:mainfrom
mattia-eleuteri:monitoring/scope-infra-dashboards
Mar 10, 2026
Merged

Andrei Kvapil (kvaps) merged 1 commit into
cozystack:mainfrom
mattia-eleuteri:monitoring/scope-infra-dashboards

Conversation

@mattia-eleuteri

@mattia-eleuteri mattia-eleuteri commented Mar 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Splits dashboards.list into tenant-facing dashboards and infrastructure dashboards (dashboards-infra.list)
  • Infrastructure dashboards (VictoriaMetrics, Flux, Hubble, LINSTOR, control-plane, etc.) are only rendered for tenant-root
  • Tenant-facing dashboards (ingress, db, kafka, nats, clickhouse, vm) remain available to all tenants

Problem

All tenants currently receive infrastructure dashboards (VictoriaMetrics, Hubble, LINSTOR, Flux, control-plane, etc.) that are only relevant to platform operators.

Relates to #2194

Test plan

  • helm template monitoring in tenant-root namespace — both lists rendered
  • helm template monitoring in a child tenant namespace — only dashboards.list rendered
  • Verify no dashboard names collide between the two lists
Scope infrastructure dashboards to tenant-root only

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Infrastructure dashboards exposed via the monitoring system for tenant-root deployments.
    • Added new ingress dashboards including vhosts and vhost-detail views.
  • Chores

    • Removed a large set of legacy dashboards to streamline the monitoring surface.
    • Reorganized dashboard generation to separate infra-specific dashboards from standard sets.

@coderabbitai

coderabbitai Bot commented Mar 10, 2026 •

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds a new infrastructure dashboards list and updates the dashboards template to conditionally emit those dashboards only when the release namespace is "tenant-root"; also prunes many infra-related entries from the main dashboards list.

Changes

Cohort / File(s) Summary
New infra dashboards list
packages/system/monitoring/dashboards-infra.list
Adds a dedicated list of infrastructure dashboard paths (main/control-plane/victoria-metrics/flux/kubevirt/dotdc/nginx/linstor/seaweedfs/hubble/etc.).
Main dashboards pruning
packages/system/monitoring/dashboards.list
Removes many infra/cluster dashboards (Victoria Metrics, control-plane, kubevirt, flux, goldpinger, main cluster dashboards); retains/adjusts select ingress and application dashboards.
Template: conditional generation
packages/system/monitoring/templates/dashboards.yaml
Adds a conditional block that reads dashboards-infra.list and emits GrafanaDashboard resources only when Release.Namespace == "tenant-root".

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
participant Helm as Helm (templates)
participant Release as Release (namespace)
participant List as dashboards-infra.list
participant Template as dashboards.yaml
participant K8s as Kubernetes API / Grafana Operator
Helm->>Release: evaluate templates with Release.Namespace
alt Release.Namespace == "tenant-root"
Template->>List: read and split lines
Template->>K8s: create GrafanaDashboard resources for each valid entry
K8s->>Grafana Operator: reconcile created GrafanaDashboard
else Release.Namespace != "tenant-root"
Template-->>Helm: skip infra dashboards block
end

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

🐰 I found the dashboards, neat in a row,

Tenant-root keeps infra where it should go,
No more clutter across every namespace,
I hop with joy at this tidy place! 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: scoping infrastructure dashboards to tenant-root only, which directly reflects the PR's core objective of restricting infrastructure dashboards from all tenants to only the tenant-root namespace.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@dosubot dosubot Bot added size/M This PR changes 30-99 lines, ignoring generated files kind/feature Categorizes issue or PR as related to a new feature labels Mar 10, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 addresses the problem of all tenants receiving infrastructure-specific monitoring dashboards that are primarily relevant to platform operators. By separating these dashboards into a dedicated list and conditionally deploying them only to the tenant-root namespace, the change aims to streamline the monitoring experience for individual tenants, providing them with only the relevant dashboards while maintaining comprehensive visibility for operators.

Highlights

  • Dashboard Separation: The existing dashboards.list was split into tenant-facing dashboards and a new dashboards-infra.list specifically for infrastructure-related monitoring.
  • Infrastructure Dashboard Scoping: Infrastructure dashboards, including those for VictoriaMetrics, Flux, Hubble, LINSTOR, and control-plane components, are now exclusively rendered for the tenant-root namespace.
  • Tenant-Facing Dashboards: Tenant-facing dashboards, such as those for ingress, databases, Kafka, NATS, ClickHouse, and VM, remain available to all tenants without restriction.

🧠 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.

Changelog
  • packages/system/monitoring/dashboards-infra.list
    • Added a new file listing infrastructure-specific Grafana dashboards.
  • packages/system/monitoring/dashboards.list
    • Removed numerous infrastructure-related dashboard entries.
    • Retained only tenant-facing dashboards.
  • packages/system/monitoring/templates/dashboards.yaml
    • Introduced logic to conditionally deploy dashboards from dashboards-infra.list only when the Helm release namespace is tenant-root.
Activity
  • The author has outlined a test plan to verify the dashboard rendering logic in tenant-root and child tenant namespaces, and to confirm no dashboard name collisions.
  • Automated summaries and release notes were generated by Claude Code and CodeRabbit.
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 (@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 (@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. ↩

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request effectively splits the dashboards into tenant-facing and infrastructure-specific lists, and correctly scopes the infrastructure dashboards to the tenant-root namespace. The changes are clear and align with the stated goal. I've suggested a refactoring in dashboards.yaml to improve maintainability by removing duplicated code, which should make future updates easier.

Comment on lines +17 to +34
{{- if eq .Release.Namespace "tenant-root" }}
{{- range (split "\n" (.Files.Get "dashboards-infra.list")) }}
{{- $parts := split "/" . }}
{{- if eq (len $parts) 2 }}
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: {{ $parts._0 }}-{{ $parts._1 }}
spec:
folder: {{ $parts._0 }}
instanceSelector:
matchLabels:
dashboards: grafana
url: http://grafana-dashboards.cozy-grafana-operator.svc/{{ . }}.json
{{- end }}
{{- 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.

medium

The newly added block from line 17 to 34 duplicates the logic from lines 1-16. To improve maintainability and avoid code duplication, you could refactor this by defining a named template.

Also, consider using .Files.Lines instead of split "\n" for more robustly parsing the list files.

Here is an example of how the refactored file could look:

{{- define "monitoring.renderDashboard" . -}}
{{- $parts := split "/" . -}}
{{- if and . (eq (len $parts) 2) -}}
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
  name: {{ $parts._0 }}-{{ $parts._1 }}
spec:
  folder: {{ $parts._0 }}
  instanceSelector:
    matchLabels:
      dashboards: grafana
  url: http://grafana-dashboards.cozy-grafana-operator.svc/{{ . }}.json
{{- end -}}
{{- end -}}

{{- range .Files.Lines "dashboards.list" -}}
{{- template "monitoring.renderDashboard" . -}}
{{- end -}}

{{- if eq .Release.Namespace "tenant-root" -}}
{{- range .Files.Lines "dashboards-infra.list" -}}
{{- template "monitoring.renderDashboard" . -}}
{{- end -}}
{{- end -}}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good suggestion for future improvement. The duplication is minimal (two similar loops iterating different list files) and refactoring into a named template would add complexity for little benefit at this stage. We can revisit if more dashboard list files are added.

Signed-off-by: Mattia Eleuteri <[email protected]>
Signed-off-by: mattia-eleuteri <[email protected]>
@mattia-eleuteri
mattia-eleuteri force-pushed the monitoring/scope-infra-dashboards branch from 185ca03 to e08c895 Compare March 10, 2026 15:58

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

🧹 Nitpick comments (1)
packages/system/monitoring/templates/dashboards.yaml (1)

17-34: Consider extracting a reusable template to reduce duplication.

The new block is nearly identical to lines 1-16, differing only in the source file. A define block could DRY this up.

♻️ Optional refactor using a helper template
+{{- define "monitoring.dashboards" -}}
+{{- range (split "\n" .) }}
+{{- $parts := split "/" . }}
+{{- if eq (len $parts) 2 }}
+---
+apiVersion: grafana.integreatly.org/v1beta1
+kind: GrafanaDashboard
+metadata:
+  name: {{ $parts._0 }}-{{ $parts._1 }}
+spec:
+  folder: {{ $parts._0 }}
+  instanceSelector:
+    matchLabels:
+      dashboards: grafana
+  url: http://grafana-dashboards.cozy-grafana-operator.svc/{{ . }}.json
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{- include "monitoring.dashboards" (.Files.Get "dashboards.list") }}
+{{- if eq .Release.Namespace "tenant-root" }}
+{{- include "monitoring.dashboards" (.Files.Get "dashboards-infra.list") }}
+{{- end }}
-{{- range (split "\n" (.Files.Get "dashboards.list")) }}
-{{- $parts := split "/" . }}
-{{- if eq (len $parts) 2 }}
----
-apiVersion: grafana.integreatly.org/v1beta1
-kind: GrafanaDashboard
-metadata:
-  name: {{ $parts._0 }}-{{ $parts._1 }}
-spec:
-  folder: {{ $parts._0 }}
-  instanceSelector:
-    matchLabels:
-      dashboards: grafana
-  url: http://grafana-dashboards.cozy-grafana-operator.svc/{{ . }}.json
-{{- end }}
-{{- end }}
-{{- if eq .Release.Namespace "tenant-root" }}
-{{- range (split "\n" (.Files.Get "dashboards-infra.list")) }}
-{{- $parts := split "/" . }}
-{{- if eq (len $parts) 2 }}
----
-apiVersion: grafana.integreatly.org/v1beta1
-kind: GrafanaDashboard
-metadata:
-  name: {{ $parts._0 }}-{{ $parts._1 }}
-spec:
-  folder: {{ $parts._0 }}
-  instanceSelector:
-    matchLabels:
-      dashboards: grafana
-  url: http://grafana-dashboards.cozy-grafana-operator.svc/{{ . }}.json
-{{- end }}
-{{- end }}
-{{- end }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/system/monitoring/templates/dashboards.yaml` around lines 17 - 34,
The new GrafanaDashboard block duplicates the earlier block; extract the
repeated manifest into a reusable Helm template (e.g., define
"renderDashboardFromList") that accepts the list filename as a parameter, moves
the shared logic (range (split "\n" (.Files.Get ...)), $parts parsing,
metadata/spec fields, and url construction) into that helper, and then call that
template twice passing "dashboards.list" and "dashboards-infra.list" (or their
existing names) instead of duplicating the block; update references to $parts
and the file input inside the helper so the behavior of name, folder and url
(including {{ . }} and $parts._0/$parts._1) is preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/system/monitoring/templates/dashboards.yaml`:
- Around line 17-34: The new GrafanaDashboard block duplicates the earlier
block; extract the repeated manifest into a reusable Helm template (e.g., define
"renderDashboardFromList") that accepts the list filename as a parameter, moves
the shared logic (range (split "\n" (.Files.Get ...)), $parts parsing,
metadata/spec fields, and url construction) into that helper, and then call that
template twice passing "dashboards.list" and "dashboards-infra.list" (or their
existing names) instead of duplicating the block; update references to $parts
and the file input inside the helper so the behavior of name, folder and url
(including {{ . }} and $parts._0/$parts._1) is preserved.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 12ab3bec-578e-4d4f-aa80-39741deeffee

📥 Commits

Reviewing files that changed from the base of the PR and between 185ca03 and e08c895.

📒 Files selected for processing (3)
  • packages/system/monitoring/dashboards-infra.list
  • packages/system/monitoring/dashboards.list
  • packages/system/monitoring/templates/dashboards.yaml
💤 Files with no reviewable changes (1)
  • packages/system/monitoring/dashboards.list
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/system/monitoring/dashboards-infra.list

@kvaps Andrei Kvapil (kvaps) left a comment

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.

LGTM, thank you for this contribution!

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Mar 10, 2026
@kvaps
Andrei Kvapil (kvaps) merged commit a240ff4 into cozystack:main Mar 10, 2026
6 checks passed
@igcherkaev

Copy link
Copy Markdown

Now cozy-monitoring's grafana doesn't get all the infra dashboards. Was it intended?

@igcherkaev

Copy link
Copy Markdown

@mattia-eleuteri

Copy link
Copy Markdown
Collaborator Author

Igor Cherkaev (@igcherkaev)
Yes, this is the intended behavior. Infrastructure dashboards are scoped to tenant-root only, so child tenants only see application-level dashboards (ingress, databases, Kafka, etc.).

The monitoring HelmRelease (which includes Grafana and dashboard resources) is deployed in tenant-root, not in cozy-monitoring. The cozy-monitoring namespace only contains collection agents (monitoring-agents, metrics-server) and has no Grafana or GrafanaDashboard resources.

Could you clarify which namespace/Grafana instance you're seeing this in? If it's in tenant-root, the infra dashboards should be present.

@igcherkaev

Copy link
Copy Markdown

mattia-eleuteri For what it's worth, when I installed cozystack (v1.1.3) from scratch with an empty bundle and default variants of pretty much everything, and after installing packages related to monitoring, I ended up with these:

$ kubectl get ingress -A | grep grafana                                                                                                                                                                                                      
cozy-monitoring   grafana-ingress         nginx          grafana.monitoring.rnn.coz.example.com        10.142.35.0   80, 443   26d
tenant-root       grafana-ingress         tenant-root    grafana.rnn.coz.example.com                   10.142.35.1   80, 443   26d

When I checked both, I found only the grafana in cozy-monitoring showing metrics related to the control plane and other infra. The one in the root tenant showed no data for them. So I assumed that the main (system) one is the one in the cozy-monitoring namespace and configured everything there (things like oidc/okta auth and roles and access).

Then when I upgraded to cozystack 1.2.1 I discovered that the dashboards were gone other than a few related to managed apps. This is when I found this PR and raised the question whether it was intended or not.

@mattia-eleuteri

Copy link
Copy Markdown
Collaborator Author

Igor Cherkaev (@igcherkaev) You're right, sorry about that! The default variant deploys monitoring to cozy-monitoring, and the condition here only checked for tenant-root. That's a bug we missed.

Fix PR: #2365

Andrei Kvapil (kvaps) added a commit that referenced this pull request Apr 9, 2026
## What this PR does

- Adds `cozy-monitoring` namespace to the infra dashboards rendering
condition in `dashboards.yaml`
- The default variant deploys the monitoring chart to `cozy-monitoring`,
but the condition from #2197 only checked for `tenant-root`, causing all
infrastructure dashboards to be missing
- This is consistent with the existing pattern in `vmagent.yaml` which
already handles both namespaces

## Release note

```release-note
[monitoring] Fix infrastructure dashboards not rendering in default variant where monitoring is deployed to cozy-monitoring namespace
```

Fixes #2349

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Infrastructure & Monitoring**
* Expanded Grafana dashboard availability across additional deployment
environments for infrastructure monitoring.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@dosubot dosubot Bot mentioned this pull request Jun 1, 2026
4 of 5 tasks
mattia-eleuteri pushed a commit to mattia-eleuteri/cozystack that referenced this pull request Jun 16, 2026
Add per-tenant KubeVirt VM dashboards (resource metrics + serial console
logs) and register them in dashboards.list.

Rebased onto main: dashboards.list now adds only the two vm/* entries —
the infra dashboards moved to dashboards-infra.list by cozystack#2197 are no
longer re-added. CPU panels plotting rate(kubevirt_vmi_cpu_*_usage_
seconds_total) now use the `short` unit with "(cores)" titles instead of
`percentunit`, so multi-vCPU VMs are no longer rendered as >100%; the
percentage-style color thresholds are dropped (absolute core thresholds
would be arbitrary across heterogeneous VM sizes).

Signed-off-by: mattia-eleuteri <[email protected]>
mattia-eleuteri pushed a commit to mattia-eleuteri/cozystack that referenced this pull request Jul 9, 2026
Add per-tenant KubeVirt VM dashboards (resource metrics + serial console
logs) and register them in dashboards.list.

Rebased onto main: dashboards.list now adds only the two vm/* entries —
the infra dashboards moved to dashboards-infra.list by cozystack#2197 are no
longer re-added. CPU panels plotting rate(kubevirt_vmi_cpu_*_usage_
seconds_total) now use the `short` unit with "(cores)" titles instead of
`percentunit`, so multi-vCPU VMs are no longer rendered as >100%; the
percentage-style color thresholds are dropped (absolute core thresholds
would be arbitrary across heterogeneous VM sizes).

Signed-off-by: mattia-eleuteri <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/feature Categorizes issue or PR as related to a new feature lgtm This PR has been approved by a maintainer size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants