feat(grafana): add support for multiple Grafana instances#7527
feat(grafana): add support for multiple Grafana instances#7527andreahlert wants to merge 11 commits intobackstage:mainfrom
Conversation
Changed Packages
|
|
Thanks for the contribution! |
Add the ability to configure multiple Grafana instances under a `grafana.hosts` config key. Each host can have its own domain, proxy path, and alerting mode. Entities are associated with a specific instance via the `grafana/source-id` annotation. Key changes: - New `grafana.hosts[]` config schema with per-host settings - New `grafana/source-id` entity annotation - Merged GrafanaApiClient to handle both unified and legacy alerting per-host instead of globally - AlertsCard resolves unifiedAlerting per-host, not from global config - Shared readHosts() config utility with proxy path validation - Full backward compatibility with single-instance `grafana.domain` Signed-off-by: André Ahlert <andre@aex.partners>
388de1b to
4eb589f
Compare
|
Hey @awanlin, this implements the multiple Grafana instances support from #1293. I based the approach on K-Phoen/backstage-plugin-grafana#76 but adapted it to the current codebase, with some improvements: per-host I've been actively contributing to community-plugins lately - created the n8n workspace (#7522), submitted a few fixes for sentry (#7523, #7525, #7526), and now this. I've been focusing on workspaces that could use some extra attention, and I'd be happy to help maintain this one going forward. |
|
Hi @awanlin, this PR implements multi-instance Grafana support as requested in #1293. I've kept full backward compatibility with the existing single-instance config while adding the new I've also opened #7528 adding unit test coverage for the API clients (GrafanaApiClient and UnifiedAlertingGrafanaApiClient), which previously had none. Would you be able to review or suggest another reviewer? Happy to address any feedback. |
|
Hi @andreahlert, while we appreciate contributions, let's hold off on conversations regarding ownership changes. I'd also suggest reading our Contributing guide as that covers the review process: https://github.com/backstage/community-plugins/blob/main/CONTRIBUTING.md#review-process. I'd also suggest you read over the AI Policy in the upstream Backstage repo as that very much applies here as well: https://github.com/backstage/backstage/blob/master/CONTRIBUTING.md#ai-use-policy-and-guidelines. This repo is volunteer run, reviews will be slow as they are based on Plugin Owner availability. Traditionally I only have time for them on Friday afternoons. I just happen to be doing some work and spotted your PRs yesterday and wanted to help set you on the right footing as they had some good and not good aspects to them. Today I'm just following up as I was ping multiple times and wanted to know why. 👍 |
Hey @awanlin, noted on all points. About the AI policy and Contributing Guide: I went through it, I take code quality seriously and like to keep things well documented, which might come across as over-structured sometimes. I wasn't trying to push for ownership either, just wanted to show I'm around and interested in helping out. And yeah, the multiple pings that's an annoying habit of mine, sorry about that 😅. I promise I'll behave, I don't want to be that guy who makes you regret checking GitHub on a Saturday. I set aside one day a week for Backstage stuff but got a bit carried away and spent some extra hours because I was enjoying the work. I contribute to other repos too so I get how volunteer time works, so no rush on the review. Thanks for taking the time to point me in the right direction. |
2dee0ac to
750a182
Compare
| grafana/alert-label-selector: service=my-service | ||
| ``` | ||
|
|
||
| If the `grafana/host-id` annotation is not set, the plugin will use the first configured host (or the `default` host created from the legacy `domain` config). |
There was a problem hiding this comment.
before this gets baked in, can we please have an option that controls the default, rather than just taking the "first configured host"? I foresee orgs that have large catalogs without the new annotation will have to take time to migrate, and the subtle behavior of "first is default" seems like it will cause future problems.
Prefer something like:
grafana:
defaultHost: production
hosts:
- id: production
domain: https://monitoring-prod.company.com
proxyPath: /grafana/production/api
unifiedAlerting: trueThere was a problem hiding this comment.
correct me if I'm wrong @robbat2, but those orgs that don't migrate they will only have a single instance, right?
There was a problem hiding this comment.
Correct - if they don't migrate, they will have a single instance.
What I want is an easier time for the orgs that DO want to migrate. Having the first entry of hosts be silently special for the migration feels too much automatic magic, vs explicitly declaring which host is the default for catalog entities that don't have the host-id declared.
b86856b to
4f88f27
Compare
f33b999 to
261ff2b
Compare
- Remove custom GrafanaConfigApi interface, use ConfigApi from @backstage/core-plugin-api - When both grafana.domain and grafana.hosts are set, ignore domain and log warning - Remove @public from GrafanaApiClient class - Rename grafana/source-id to grafana/host-id annotation - Remove per-host grafanaDashboardSearchLimit/grafanaDashboardMaxPages, keep global only - Mark global grafanaDashboardSearchLimit/grafanaDashboardMaxPages as @deprecated Signed-off-by: André Ahlert <andre@aex.partners>
Co-authored-by: Vincenzo Scamporlino <vincenzos@spotify.com> Signed-off-by: André Ahlert <andre@aex.partners>
Signed-off-by: André Ahlert <andre@aex.partners>
Signed-off-by: André Ahlert <andre@aex.partners>
Add eslint-disable comments for intentional use of deprecated config keys (grafana.domain, grafana.proxyPath, grafana.unifiedAlerting, grafanaDashboardSearchLimit, grafanaDashboardMaxPages) so CI list-deprecations check passes while keeping backward compatibility. - Fix indent of eslint-enable in config.ts - Use dashboardSearchLimit/dashboardMaxPages in GrafanaApiClientOptions to match plugin.ts and apis.ts (fix type checking). Signed-off-by: André Ahlert <andre@aex.partners>
Add defaultHostId to GrafanaApiClientOptions in report.api.md so check api reports and generate API reference CI step passes. Signed-off-by: André Ahlert <andre@aex.partners>
- Regenerated report.api.md and report-alpha.api.md using backstage-repo-tools\n- Includes the new defaultHostId property in GrafanaApiClientOptions\n- Fixes CI validation failure on 'check api reports and generate API reference' Signed-off-by: André Ahlert <andre@aex.partners>
Regenerate report.api.md and report-alpha.api.md to match the current API Extractor output used in CI, fixing the build:api-reports:only --ci failure on PR 7527. Signed-off-by: André Ahlert <andre@aex.partners>
d0fbce8 to
065ecc9
Compare
Update EntityGrafanaAlertsCard and EntityGrafanaDashboardsCard signatures in report.api.md to match API Extractor output from CI (Node 22/24), resolving the remaining api report mismatch. Signed-off-by: André Ahlert <andre@aex.partners>
Update report-alpha.api.md from API Extractor output generated under Node 22/24 to match CI expectations and fix build:api-reports:only --ci failures. Signed-off-by: André Ahlert <andre@aex.partners>
Summary
Closes #1293
Adds the ability to configure multiple Grafana instances, allowing organizations with separate Grafana deployments (e.g., production and staging) to use them all within Backstage.
grafana.hosts[]configuration with per-hostdomain,proxyPath,unifiedAlerting, and search settingsgrafana/source-identity annotation to associate entities with specific Grafana instancesgrafana.domainconfigurationChanges
Core:
config.d.ts- Addedhosts[]config schemasrc/types.ts- AddedGrafanaHostinterfacesrc/constants.ts- AddedGRAFANA_ANNOTATION_SOURCE_IDandsourceIdFromEntity()src/api.ts- Merged two API client classes into one multi-host client withisUnifiedAlerting()per-host resolutionsrc/config.ts- SharedreadHosts()utility with validationsrc/plugin.ts/src/alpha/apis.ts- Updated factories using shared configComponents:
AlertsCard.tsx- Uses per-hostisUnifiedAlerting()instead of global configDashboardsCard.tsx- PassessourceIdto API callsTests (+24 new tests):
api.test.ts- Host resolution,isUnifiedAlertingper-host, fallback, error casesconfig.test.ts- Config reading, validation, proxy path collisionconstants.test.ts-sourceIdFromEntitywith/without annotationAlertsCard.test.tsx- Integration tests for per-host unified alerting selector flowDocs:
setup.md- Multi-instance configuration guidealerts-on-component-page.md/dashboards-on-component-page.md-grafana/source-idusageConfiguration example
Test plan
grafana/source-idfalls back to default host