Compare commits

..

2 Commits

Author SHA1 Message Date
Piotr Jamróz f2f73707c6 Update translations 2025-12-17 15:00:06 +01:00
Piotr Jamróz a13bd73b9a Explore: Reset hidden series 2025-12-17 14:40:02 +01:00
2248 changed files with 39751 additions and 106603 deletions
+4 -6
View File
@@ -24,6 +24,7 @@
/NOTICE.md @torkelo /NOTICE.md @torkelo
/README.md @grafana/docs-grafana /README.md @grafana/docs-grafana
/ROADMAP.md @torkelo /ROADMAP.md @torkelo
/SECURITY.md @grafana/security-team
/SUPPORT.md @torkelo /SUPPORT.md @torkelo
/WORKFLOW.md @torkelo /WORKFLOW.md @torkelo
/contribute/ @grafana/grafana-community-support /contribute/ @grafana/grafana-community-support
@@ -94,6 +95,7 @@
/apps/shorturl/ @grafana/sharing-squad /apps/shorturl/ @grafana/sharing-squad
/apps/secret/ @grafana/grafana-operator-experience-squad /apps/secret/ @grafana/grafana-operator-experience-squad
/apps/scope/ @grafana/grafana-operator-experience-squad /apps/scope/ @grafana/grafana-operator-experience-squad
/apps/investigations/ @fcjack @matryer @svennergr
/apps/advisor/ @grafana/plugins-platform-backend /apps/advisor/ @grafana/plugins-platform-backend
/apps/iam/ @grafana/access-squad /apps/iam/ @grafana/access-squad
/apps/sdk.mk @grafana/grafana-app-platform-squad /apps/sdk.mk @grafana/grafana-app-platform-squad
@@ -424,7 +426,6 @@ i18next.config.ts @grafana/grafana-frontend-platform
/public/locales/enterprise/i18next.config.ts @grafana/grafana-frontend-platform /public/locales/enterprise/i18next.config.ts @grafana/grafana-frontend-platform
/public/app/core/internationalization/ @grafana/grafana-frontend-platform /public/app/core/internationalization/ @grafana/grafana-frontend-platform
/e2e/ @grafana/grafana-frontend-platform /e2e/ @grafana/grafana-frontend-platform
/e2e-playwright/alerting-suite/ @grafana/alerting-frontend
/e2e-playwright/cloud-plugins-suite/ @grafana/partner-datasources /e2e-playwright/cloud-plugins-suite/ @grafana/partner-datasources
/e2e-playwright/dashboard-new-layouts/ @grafana/dashboards-squad /e2e-playwright/dashboard-new-layouts/ @grafana/dashboards-squad
/e2e-playwright/dashboard-cujs/ @grafana/dashboards-squad /e2e-playwright/dashboard-cujs/ @grafana/dashboards-squad
@@ -440,7 +441,6 @@ i18next.config.ts @grafana/grafana-frontend-platform
/e2e-playwright/dashboards/TestDashboard.json @grafana/dashboards-squad @grafana/grafana-search-navigate-organise /e2e-playwright/dashboards/TestDashboard.json @grafana/dashboards-squad @grafana/grafana-search-navigate-organise
/e2e-playwright/dashboards/TestV2Dashboard.json @grafana/dashboards-squad /e2e-playwright/dashboards/TestV2Dashboard.json @grafana/dashboards-squad
/e2e-playwright/dashboards/V2DashWithRepeats.json @grafana/dashboards-squad /e2e-playwright/dashboards/V2DashWithRepeats.json @grafana/dashboards-squad
/e2e-playwright/dashboards/V2DashWithRowRepeats.json @grafana/dashboards-squad
/e2e-playwright/dashboards/V2DashWithTabRepeats.json @grafana/dashboards-squad /e2e-playwright/dashboards/V2DashWithTabRepeats.json @grafana/dashboards-squad
/e2e-playwright/dashboards-suite/adhoc-filter-from-panel.spec.ts @grafana/datapro /e2e-playwright/dashboards-suite/adhoc-filter-from-panel.spec.ts @grafana/datapro
/e2e-playwright/dashboards-suite/dashboard-browse-nested.spec.ts @grafana/grafana-search-navigate-organise /e2e-playwright/dashboards-suite/dashboard-browse-nested.spec.ts @grafana/grafana-search-navigate-organise
@@ -501,6 +501,7 @@ i18next.config.ts @grafana/grafana-frontend-platform
/e2e-playwright/various-suite/filter-annotations.spec.ts @grafana/dashboards-squad /e2e-playwright/various-suite/filter-annotations.spec.ts @grafana/dashboards-squad
/e2e-playwright/various-suite/frontend-sandbox-app.spec.ts @grafana/plugins-platform-frontend /e2e-playwright/various-suite/frontend-sandbox-app.spec.ts @grafana/plugins-platform-frontend
/e2e-playwright/various-suite/frontend-sandbox-datasource.spec.ts @grafana/plugins-platform-frontend /e2e-playwright/various-suite/frontend-sandbox-datasource.spec.ts @grafana/plugins-platform-frontend
/e2e-playwright/various-suite/gauge.spec.ts @grafana/dataviz-squad
/e2e-playwright/various-suite/grafana-datasource-random-walk.spec.ts @grafana/grafana-frontend-platform /e2e-playwright/various-suite/grafana-datasource-random-walk.spec.ts @grafana/grafana-frontend-platform
/e2e-playwright/various-suite/graph-auto-migrate.spec.ts @grafana/dataviz-squad /e2e-playwright/various-suite/graph-auto-migrate.spec.ts @grafana/dataviz-squad
/e2e-playwright/various-suite/inspect-drawer.spec.ts @grafana/dashboards-squad /e2e-playwright/various-suite/inspect-drawer.spec.ts @grafana/dashboards-squad
@@ -519,7 +520,7 @@ i18next.config.ts @grafana/grafana-frontend-platform
/e2e-playwright/various-suite/solo-route.spec.ts @grafana/dashboards-squad /e2e-playwright/various-suite/solo-route.spec.ts @grafana/dashboards-squad
/e2e-playwright/various-suite/trace-view-scrolling.spec.ts @grafana/observability-traces-and-profiling /e2e-playwright/various-suite/trace-view-scrolling.spec.ts @grafana/observability-traces-and-profiling
/e2e-playwright/various-suite/verify-i18n.spec.ts @grafana/grafana-frontend-platform /e2e-playwright/various-suite/verify-i18n.spec.ts @grafana/grafana-frontend-platform
/e2e-playwright/various-suite/visualization-suggestions*.spec.ts @grafana/dataviz-squad /e2e-playwright/various-suite/visualization-suggestions.spec.ts @grafana/dataviz-squad
/e2e-playwright/various-suite/perf-test.spec.ts @grafana/grafana-frontend-platform /e2e-playwright/various-suite/perf-test.spec.ts @grafana/grafana-frontend-platform
# Packages # Packages
@@ -543,7 +544,6 @@ i18next.config.ts @grafana/grafana-frontend-platform
/packages/grafana-data/tsconfig.json @grafana/grafana-frontend-platform /packages/grafana-data/tsconfig.json @grafana/grafana-frontend-platform
/packages/grafana-data/test/ @grafana/grafana-frontend-platform /packages/grafana-data/test/ @grafana/grafana-frontend-platform
/packages/grafana-data/typings/ @grafana/grafana-frontend-platform /packages/grafana-data/typings/ @grafana/grafana-frontend-platform
/packages/grafana-data/scripts/ @grafana/grafana-frontend-platform
/packages/grafana-data/src/**/*logs* @grafana/observability-logs /packages/grafana-data/src/**/*logs* @grafana/observability-logs
/packages/grafana-data/src/context/plugins/ @grafana/plugins-platform-frontend /packages/grafana-data/src/context/plugins/ @grafana/plugins-platform-frontend
@@ -659,7 +659,6 @@ i18next.config.ts @grafana/grafana-frontend-platform
/packages/grafana-runtime/src/services/LocationService.tsx @grafana/grafana-search-navigate-organise /packages/grafana-runtime/src/services/LocationService.tsx @grafana/grafana-search-navigate-organise
/packages/grafana-runtime/src/services/LocationSrv.ts @grafana/grafana-search-navigate-organise /packages/grafana-runtime/src/services/LocationSrv.ts @grafana/grafana-search-navigate-organise
/packages/grafana-runtime/src/services/live.ts @grafana/dashboards-squad /packages/grafana-runtime/src/services/live.ts @grafana/dashboards-squad
/packages/grafana-runtime/src/services/pluginMeta @grafana/plugins-platform-frontend
/packages/grafana-runtime/src/utils/chromeHeaderHeight.ts @grafana/grafana-search-navigate-organise /packages/grafana-runtime/src/utils/chromeHeaderHeight.ts @grafana/grafana-search-navigate-organise
/packages/grafana-runtime/src/utils/DataSourceWithBackend* @grafana/grafana-datasources-core-services /packages/grafana-runtime/src/utils/DataSourceWithBackend* @grafana/grafana-datasources-core-services
/packages/grafana-runtime/src/utils/licensing.ts @grafana/grafana-operator-experience-squad /packages/grafana-runtime/src/utils/licensing.ts @grafana/grafana-operator-experience-squad
@@ -1278,7 +1277,6 @@ embed.go @grafana/grafana-as-code
/.github/workflows/i18n-crowdin-download.yml @grafana/grafana-frontend-platform /.github/workflows/i18n-crowdin-download.yml @grafana/grafana-frontend-platform
/.github/workflows/i18n-crowdin-create-tasks.yml @grafana/grafana-frontend-platform /.github/workflows/i18n-crowdin-create-tasks.yml @grafana/grafana-frontend-platform
/.github/workflows/i18n-verify.yml @grafana/grafana-frontend-platform /.github/workflows/i18n-verify.yml @grafana/grafana-frontend-platform
/.github/workflows/deploy-storybook.yml @grafana/grafana-frontend-platform
/.github/workflows/deploy-storybook-preview.yml @grafana/grafana-frontend-platform /.github/workflows/deploy-storybook-preview.yml @grafana/grafana-frontend-platform
/.github/workflows/scripts/crowdin/create-tasks.ts @grafana/grafana-frontend-platform /.github/workflows/scripts/crowdin/create-tasks.ts @grafana/grafana-frontend-platform
/.github/workflows/scripts/publish-frontend-metrics.mts @grafana/grafana-frontend-platform /.github/workflows/scripts/publish-frontend-metrics.mts @grafana/grafana-frontend-platform
+11 -1
View File
@@ -82,6 +82,14 @@ inputs:
description: Docker registry of produced images description: Docker registry of produced images
default: docker.io default: docker.io
required: false required: false
ubuntu-base:
type: string
default: 'ubuntu:22.04'
required: false
alpine-base:
type: string
default: 'alpine:3.22'
required: false
outputs: outputs:
dist-dir: dist-dir:
description: Directory where artifacts are placed description: Directory where artifacts are placed
@@ -126,11 +134,13 @@ runs:
UBUNTU_TAG_FORMAT: ${{ inputs.docker-tag-format-ubuntu }} UBUNTU_TAG_FORMAT: ${{ inputs.docker-tag-format-ubuntu }}
CHECKSUM: ${{ inputs.checksum }} CHECKSUM: ${{ inputs.checksum }}
VERIFY: ${{ inputs.verify }} VERIFY: ${{ inputs.verify }}
ALPINE_BASE: ${{ inputs.alpine-base }}
UBUNTU_BASE: ${{ inputs.ubuntu-base }}
with: with:
verb: run verb: run
dagger-flags: --verbose=0 dagger-flags: --verbose=0
version: 0.18.8 version: 0.18.8
args: go run -C ${GRAFANA_PATH} ./pkg/build/cmd artifacts --artifacts ${ARTIFACTS} --grafana-dir=${GRAFANA_PATH} --enterprise-dir=${ENTERPRISE_PATH} --version=${VERSION} --patches-repo=${PATCHES_REPO} --patches-ref=${PATCHES_REF} --patches-path=${PATCHES_PATH} --build-id=${BUILD_ID} --tag-format="${TAG_FORMAT}" --ubuntu-tag-format="${UBUNTU_TAG_FORMAT}" --org=${DOCKER_ORG} --registry=${DOCKER_REGISTRY} --checksum=${CHECKSUM} --verify=${VERIFY} > $OUTFILE args: go run -C ${GRAFANA_PATH} ./pkg/build/cmd artifacts --artifacts ${ARTIFACTS} --grafana-dir=${GRAFANA_PATH} --alpine-base=${ALPINE_BASE} --ubuntu-base=${UBUNTU_BASE} --enterprise-dir=${ENTERPRISE_PATH} --version=${VERSION} --patches-repo=${PATCHES_REPO} --patches-ref=${PATCHES_REF} --patches-path=${PATCHES_PATH} --build-id=${BUILD_ID} --tag-format="${TAG_FORMAT}" --ubuntu-tag-format="${UBUNTU_TAG_FORMAT}" --org=${DOCKER_ORG} --registry=${DOCKER_REGISTRY} --checksum=${CHECKSUM} --verify=${VERIFY} > $OUTFILE
- id: output - id: output
shell: bash shell: bash
env: env:
@@ -14,9 +14,6 @@ outputs:
frontend: frontend:
description: Whether the frontend or self has changed in any way description: Whether the frontend or self has changed in any way
value: ${{ steps.changed-files.outputs.frontend_any_changed || 'true' }} value: ${{ steps.changed-files.outputs.frontend_any_changed || 'true' }}
frontend-packages:
description: Whether any frontend packages have changed
value: ${{ steps.changed-files.outputs.frontend_packages_any_changed || 'true' }}
e2e: e2e:
description: Whether the e2e tests or self have changed in any way description: Whether the e2e tests or self have changed in any way
value: ${{ steps.changed-files.outputs.e2e_any_changed == 'true' || value: ${{ steps.changed-files.outputs.e2e_any_changed == 'true' ||
@@ -98,17 +95,9 @@ runs:
- 'nx.json' - 'nx.json'
- 'tsconfig.json' - 'tsconfig.json'
- '.yarn/**' - '.yarn/**'
- 'apps/dashboard/pkg/migration/**'
- '${{ inputs.self }}'
frontend_packages:
- '.github/actions/checkout/**'
- '.github/actions/change-detection/**'
- 'packages/**'
- './scripts/validate-npm-packages.sh'
- '${{ inputs.self }}' - '${{ inputs.self }}'
e2e: e2e:
- 'e2e/**' - 'e2e/**'
- 'e2e-playwright/**'
- '.github/actions/setup-enterprise/**' - '.github/actions/setup-enterprise/**'
- '.github/actions/checkout/**' - '.github/actions/checkout/**'
- 'emails/**' - 'emails/**'
@@ -162,8 +151,6 @@ runs:
echo " --> ${{ steps.changed-files.outputs.backend_all_changed_files }}" echo " --> ${{ steps.changed-files.outputs.backend_all_changed_files }}"
echo "Frontend: ${{ steps.changed-files.outputs.frontend_any_changed || 'true' }}" echo "Frontend: ${{ steps.changed-files.outputs.frontend_any_changed || 'true' }}"
echo " --> ${{ steps.changed-files.outputs.frontend_all_changed_files }}" echo " --> ${{ steps.changed-files.outputs.frontend_all_changed_files }}"
echo "Frontend packages: ${{ steps.changed-files.outputs.frontend_packages_any_changed || 'true' }}"
echo " --> ${{ steps.changed-files.outputs.frontend_packages_all_changed_files }}"
echo "E2E: ${{ steps.changed-files.outputs.e2e_any_changed || 'true' }}" echo "E2E: ${{ steps.changed-files.outputs.e2e_any_changed || 'true' }}"
echo " --> ${{ steps.changed-files.outputs.e2e_all_changed_files }}" echo " --> ${{ steps.changed-files.outputs.e2e_all_changed_files }}"
echo " --> ${{ steps.changed-files.outputs.backend_all_changed_files }}" echo " --> ${{ steps.changed-files.outputs.backend_all_changed_files }}"
+1 -1
View File
@@ -4,7 +4,7 @@ description: Sets up a node.js environment with presets for the Grafana reposito
runs: runs:
using: "composite" using: "composite"
steps: steps:
- uses: actions/setup-node@v6 - uses: actions/setup-node@v4
with: with:
node-version-file: '.nvmrc' node-version-file: '.nvmrc'
cache: 'yarn' cache: 'yarn'
+1
View File
@@ -19,6 +19,7 @@ updates:
- "/apps/dashboard" - "/apps/dashboard"
- "/apps/folder" - "/apps/folder"
- "/apps/iam" - "/apps/iam"
- "/apps/investigations"
- "/apps/playlist" - "/apps/playlist"
- "/apps/plugins" - "/apps/plugins"
- "/apps/preferences" - "/apps/preferences"
+1 -3
View File
@@ -365,9 +365,7 @@
"type": "changedfiles", "type": "changedfiles",
"matches": [ "matches": [
"public/app/plugins/panel/gauge/**/*", "public/app/plugins/panel/gauge/**/*",
"public/app/plugins/panel/radialbar/**/*", "/packages/grafana-ui/src/components/Gauge/**/*"
"/packages/grafana-ui/src/components/Gauge/**/*",
"/packages/grafana-ui/src/components/RadialGauge/**/*"
], ],
"action": "updateLabel", "action": "updateLabel",
"addLabel": "area/panel/gauge" "addLabel": "area/panel/gauge"
-79
View File
@@ -1,79 +0,0 @@
name: Deploy Storybook
on:
workflow_dispatch:
# push:
# branches:
# - main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions: {}
jobs:
detect-changes:
# Only run in grafana/grafana
if: github.repository == 'grafana/grafana'
name: Detect whether code changed
runs-on: ubuntu-latest
permissions:
contents: read
outputs:
changed-frontend-packages: ${{ steps.detect-changes.outputs.frontend-packages }}
steps:
- uses: actions/checkout@v5
with:
persist-credentials: true # required to get more history in the changed-files action
fetch-depth: 2
- name: Detect changes
id: detect-changes
uses: ./.github/actions/change-detection
with:
self: .github/workflows/deploy-storybook.yml
deploy-storybook:
name: Deploy Storybook
runs-on: ubuntu-latest
needs: detect-changes
# Only run in grafana/grafana
if: github.repository == 'grafana/grafana' && needs.detect-changes.outputs.changed-frontend-packages == 'true'
permissions:
contents: read
id-token: write
env:
BUCKET_NAME: grafana-storybook
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Setup Node.js
uses: ./.github/actions/setup-node
- name: Install dependencies
run: yarn install --immutable
- name: Build storybook
run: yarn storybook:build
# Create the GCS folder name
# Right now, this just returns "canary"
# But we'll expand this to work for "latest" as well in the future
- name: Create deploy name
id: create-deploy-name
run: |
echo "deploy-name=canary" >> "$GITHUB_OUTPUT"
- name: Upload Storybook
uses: grafana/shared-workflows/actions/push-to-gcs@main
with:
environment: prod
bucket: ${{ env.BUCKET_NAME }}
bucket_path: ${{ steps.create-deploy-name.outputs.deploy-name }}
path: packages/grafana-ui/dist/storybook
service_account: github-gf-storybook-deploy@grafanalabs-workload-identity.iam.gserviceaccount.com
parent: false
+30 -36
View File
@@ -17,7 +17,6 @@ jobs:
outputs: outputs:
changed: ${{ steps.detect-changes.outputs.frontend }} changed: ${{ steps.detect-changes.outputs.frontend }}
prettier: ${{ steps.detect-changes.outputs.frontend == 'true' || steps.detect-changes.outputs.docs == 'true' }} prettier: ${{ steps.detect-changes.outputs.frontend == 'true' || steps.detect-changes.outputs.docs == 'true' }}
changed-frontend-packages: ${{ steps.detect-changes.outputs.frontend-packages }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with: with:
@@ -43,8 +42,11 @@ jobs:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - uses: actions/setup-node@v6
uses: ./.github/actions/setup-node with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- run: yarn install --immutable --check-cache - run: yarn install --immutable --check-cache
- run: yarn run prettier:check - run: yarn run prettier:check
- run: yarn run lint - run: yarn run lint
@@ -61,8 +63,11 @@ jobs:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - uses: actions/setup-node@v6
uses: ./.github/actions/setup-node with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Setup Enterprise - name: Setup Enterprise
uses: ./.github/actions/setup-enterprise uses: ./.github/actions/setup-enterprise
with: with:
@@ -84,8 +89,11 @@ jobs:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - uses: actions/setup-node@v6
uses: ./.github/actions/setup-node with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- run: yarn install --immutable --check-cache - run: yarn install --immutable --check-cache
- run: yarn run typecheck - run: yarn run typecheck
lint-frontend-typecheck-enterprise: lint-frontend-typecheck-enterprise:
@@ -101,8 +109,11 @@ jobs:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - uses: actions/setup-node@v6
uses: ./.github/actions/setup-node with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Setup Enterprise - name: Setup Enterprise
uses: ./.github/actions/setup-enterprise uses: ./.github/actions/setup-enterprise
with: with:
@@ -122,8 +133,11 @@ jobs:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - uses: actions/setup-node@v6
uses: ./.github/actions/setup-node with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- run: yarn install --immutable --check-cache - run: yarn install --immutable --check-cache
- name: Generate API clients - name: Generate API clients
run: | run: |
@@ -150,8 +164,11 @@ jobs:
- uses: actions/checkout@v5 - uses: actions/checkout@v5
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Node - uses: actions/setup-node@v6
uses: ./.github/actions/setup-node with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Setup Enterprise - name: Setup Enterprise
uses: ./.github/actions/setup-enterprise uses: ./.github/actions/setup-enterprise
with: with:
@@ -170,26 +187,3 @@ jobs:
echo "${uncommited_error_message}" echo "${uncommited_error_message}"
exit 1 exit 1
fi fi
lint-frontend-packed-packages:
needs: detect-changes
permissions:
contents: read
id-token: write
if: github.event_name == 'pull_request' && needs.detect-changes.outputs.changed-frontend-packages == 'true'
name: Verify packed frontend packages
runs-on: ubuntu-latest
steps:
- name: Checkout build commit
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Setup Node
uses: ./.github/actions/setup-node
- name: Install dependencies
run: yarn install --immutable
- name: Build and pack packages
run: |
yarn run packages:build
yarn run packages:pack
- name: Validate packages
run: ./scripts/validate-npm-packages.sh
+8 -2
View File
@@ -67,6 +67,14 @@ linters:
deny: deny:
- pkg: github.com/grafana/grafana/pkg - pkg: github.com/grafana/grafana/pkg
desc: apiserver is not allowed to import grafana core desc: apiserver is not allowed to import grafana core
apps-investigation:
list-mode: lax
files:
- ./apps/investigations/*
- ./apps/investigations/**/*
deny:
- pkg: github.com/grafana/grafana/pkg
desc: apps/investigations is not allowed to import grafana core
apps-playlist: apps-playlist:
list-mode: lax list-mode: lax
files: files:
@@ -121,8 +129,6 @@ linters:
- '**/pkg/tsdb/zipkin/**/*' - '**/pkg/tsdb/zipkin/**/*'
- '**/pkg/tsdb/jaeger/*' - '**/pkg/tsdb/jaeger/*'
- '**/pkg/tsdb/jaeger/**/*' - '**/pkg/tsdb/jaeger/**/*'
- '**/pkg/tsdb/elasticsearch/*'
- '**/pkg/tsdb/elasticsearch/**/*'
deny: deny:
- pkg: github.com/grafana/grafana/pkg/api - pkg: github.com/grafana/grafana/pkg/api
desc: Core plugins are not allowed to depend on Grafana core packages desc: Core plugins are not allowed to depend on Grafana core packages
@@ -1,13 +0,0 @@
diff --git a/dist/builder-manager/index.js b/dist/builder-manager/index.js
index ac8ac6a5f6a3b7852c4064e93dc9acd3201289e6..34a0a5a5c38dd7fe525c9ebd382a10a451d4d4f3 100644
--- a/dist/builder-manager/index.js
+++ b/dist/builder-manager/index.js
@@ -1974,7 +1974,7 @@ var pa = /^\/($|\?)/, G, C, xt = /* @__PURE__ */ o(async (e) => {
bundle: !0,
minify: !0,
sourcemap: !1,
- conditions: ["browser", "module", "default"],
+ conditions: ["@grafana-app/source", "browser", "module", "default"],
jsxFactory: "React.createElement",
jsxFragment: "React.Fragment",
jsx: "transform",
+1 -1
View File
@@ -91,7 +91,6 @@ COPY pkg/storage/unified/resource pkg/storage/unified/resource
COPY pkg/storage/unified/resourcepb pkg/storage/unified/resourcepb COPY pkg/storage/unified/resourcepb pkg/storage/unified/resourcepb
COPY pkg/storage/unified/apistore pkg/storage/unified/apistore COPY pkg/storage/unified/apistore pkg/storage/unified/apistore
COPY pkg/semconv pkg/semconv COPY pkg/semconv pkg/semconv
COPY pkg/plugins pkg/plugins
COPY pkg/aggregator pkg/aggregator COPY pkg/aggregator pkg/aggregator
COPY apps/playlist apps/playlist COPY apps/playlist apps/playlist
COPY apps/quotas apps/quotas COPY apps/quotas apps/quotas
@@ -104,6 +103,7 @@ COPY apps/collections apps/collections
COPY apps/provisioning apps/provisioning COPY apps/provisioning apps/provisioning
COPY apps/secret apps/secret COPY apps/secret apps/secret
COPY apps/scope apps/scope COPY apps/scope apps/scope
COPY apps/investigations apps/investigations
COPY apps/logsdrilldown apps/logsdrilldown COPY apps/logsdrilldown apps/logsdrilldown
COPY apps/advisor apps/advisor COPY apps/advisor apps/advisor
COPY apps/dashboard apps/dashboard COPY apps/dashboard apps/dashboard
-5
View File
@@ -227,10 +227,6 @@ fix-cue:
gen-jsonnet: gen-jsonnet:
go generate ./devenv/jsonnet go generate ./devenv/jsonnet
.PHONY: gen-themes
gen-themes:
go generate ./pkg/services/preference
.PHONY: update-workspace .PHONY: update-workspace
update-workspace: gen-go update-workspace: gen-go
@echo "updating workspace" @echo "updating workspace"
@@ -248,7 +244,6 @@ build-go-fast: ## Build all Go binaries without updating workspace.
.PHONY: build-backend .PHONY: build-backend
build-backend: ## Build Grafana backend. build-backend: ## Build Grafana backend.
@echo "build backend" @echo "build backend"
$(MAKE) gen-themes
$(GO) run build.go $(GO_BUILD_FLAGS) build-backend $(GO) run build.go $(GO_BUILD_FLAGS) build-backend
.PHONY: build-air .PHONY: build-air
+29
View File
@@ -0,0 +1,29 @@
# Reporting security issues
If you think you have found a security vulnerability, we have two routes for reporting security issues.
Important: Whichever route you choose, we ask you to not disclose the vulnerability before it has been fixed and announced, unless you received a response from the Grafana Labs security team that you can do so.
[Full guidance on reporting a security issue can be found here](https://grafana.com/legal/report-a-security-issue/).
This product is in scope for our Bug Bounty Program. To submit a vulnerability report, please visit [Grafana Labs Bug Bounty page](https://app.intigriti.com/programs/grafanalabs/grafanaossbbp/detail) and follow the instructions provided. Our security team will review your submission and get back to you as soon as possible.
---
For products and services outside the scope of our bug bounty program, or if you do not wish to receive a bounty, you can report issues directly to us via email at security@grafana.com. This address can be used for all of Grafana Labs open source and commercial products (including but not limited to Grafana, Grafana Cloud, Grafana Enterprise, and grafana.com).
Please encrypt your message to us; please use our PGP key. The key fingerprint is:
225E 6A9B BB15 A37E 95EB 6312 C66A 51CC B44C 27E0
The key is available from [keyserver.ubuntu.com](https://keyserver.ubuntu.com/pks/lookup?search=0x225E6A9BBB15A37E95EB6312C66A51CCB44C27E0&fingerprint=on&op=index).
Grafana Labs will send you a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
**Important:** We ask you to not disclose the vulnerability before it have been fixed and announced, unless you received a response from the Grafana Labs security team that you can do so.
## Security announcements
We will post a summary, remediation, and mitigation details for any patch containing security fixes on the Grafana blog. The security announcement blog posts will be tagged with the [security tag](https://grafana.com/tags/security/).
You can also track security announcements via the [RSS feed](https://grafana.com/tags/security/index.xml).
+11 -13
View File
@@ -54,7 +54,6 @@ require (
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect github.com/BurntSushi/toml v1.5.0 // indirect
github.com/Machiel/slugify v1.0.1 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect
@@ -68,14 +67,14 @@ require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/at-wat/mqtt-go v0.19.6 // indirect github.com/at-wat/mqtt-go v0.19.6 // indirect
github.com/aws/aws-sdk-go v1.55.7 // indirect github.com/aws/aws-sdk-go v1.55.7 // indirect
github.com/aws/aws-sdk-go-v2 v1.40.0 // indirect github.com/aws/aws-sdk-go-v2 v1.39.1 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.18.14 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.8 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.8 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.8 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 // indirect
github.com/aws/smithy-go v1.23.2 // indirect github.com/aws/smithy-go v1.23.1 // indirect
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect
github.com/benbjohnson/clock v1.3.5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
@@ -158,18 +157,17 @@ require (
github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/google/wire v0.7.0 // indirect github.com/google/wire v0.7.0 // indirect
github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f // indirect github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7 // indirect
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect
github.com/grafana/dataplane/sdata v0.0.9 // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect
github.com/grafana/grafana-aws-sdk v1.4.2 // indirect github.com/grafana/grafana-aws-sdk v1.3.0 // indirect
github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 // indirect github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 // indirect
github.com/grafana/grafana/apps/provisioning v0.0.0 // indirect github.com/grafana/grafana/apps/provisioning v0.0.0 // indirect
github.com/grafana/grafana/pkg/apiserver v0.0.0 // indirect github.com/grafana/grafana/pkg/apiserver v0.0.0 // indirect
github.com/grafana/grafana/pkg/semconv v0.0.0-20250804150913-990f1c69ecc2 // indirect
github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grafana/otel-profiling-go v0.5.1 // indirect
github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect
github.com/grafana/sqlds/v5 v5.0.3 // indirect github.com/grafana/sqlds/v4 v4.2.7 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
+32 -34
View File
@@ -115,8 +115,6 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapp
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
github.com/IBM/pgxpoolprometheus v1.1.2 h1:sHJwxoL5Lw4R79Zt+H4Uj1zZ4iqXJLdk7XDE7TPs97U= github.com/IBM/pgxpoolprometheus v1.1.2 h1:sHJwxoL5Lw4R79Zt+H4Uj1zZ4iqXJLdk7XDE7TPs97U=
github.com/IBM/pgxpoolprometheus v1.1.2/go.mod h1:+vWzISN6S9ssgurhUNmm6AlXL9XLah3TdWJktquKTR8= github.com/IBM/pgxpoolprometheus v1.1.2/go.mod h1:+vWzISN6S9ssgurhUNmm6AlXL9XLah3TdWJktquKTR8=
github.com/Machiel/slugify v1.0.1 h1:EfWSlRWstMadsgzmiV7d0yVd2IFlagWH68Q+DcYCm4E=
github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
@@ -173,44 +171,44 @@ github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= github.com/aws/aws-sdk-go v1.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE=
github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc= github.com/aws/aws-sdk-go-v2 v1.39.1 h1:fWZhGAwVRK/fAN2tmt7ilH4PPAE11rDj7HytrmbZ2FE=
github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY=
github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y= github.com/aws/aws-sdk-go-v2/config v1.31.10 h1:7LllDZAegXU3yk41mwM6KcPu0wmjKGQB1bg99bNdQm4=
github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c= github.com/aws/aws-sdk-go-v2/config v1.31.10/go.mod h1:Ge6gzXPjqu4v0oHvgAwvGzYcK921GU0hQM25WF/Kl+8=
github.com/aws/aws-sdk-go-v2/credentials v1.18.21 h1:56HGpsgnmD+2/KpG0ikvvR8+3v3COCwaF4r+oWwOeNA= github.com/aws/aws-sdk-go-v2/credentials v1.18.14 h1:TxkI7QI+sFkTItN/6cJuMZEIVMFXeu2dI1ZffkXngKI=
github.com/aws/aws-sdk-go-v2/credentials v1.18.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= github.com/aws/aws-sdk-go-v2/credentials v1.18.14/go.mod h1:12x4Uw/vijC11XkctTjy92TNCQ+UnNJkT7fzX0Yd93E=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 h1:T1brd5dR3/fzNFAQch/iBKeX07/ffu/cLu+q+RuzEWk= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.8 h1:gLD09eaJUdiszm7vd1btiQUYE0Hj+0I2b8AS+75z9AY=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.8/go.mod h1:4RW3oMPt1POR74qVOC4SbubxAwdP4pCT0nSw3jycOU4=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84 h1:cTXRdLkpBanlDwISl+5chq5ui1d1YWg4PWMR9c3kXyw= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84 h1:cTXRdLkpBanlDwISl+5chq5ui1d1YWg4PWMR9c3kXyw=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84/go.mod h1:kwSy5X7tfIHN39uucmjQVs2LvDdXEjQucgQQEqCggEo= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84/go.mod h1:kwSy5X7tfIHN39uucmjQVs2LvDdXEjQucgQQEqCggEo=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.8 h1:6bgAZgRyT4RoFWhxS+aoGMFyE0cD1bSzFnEEi4bFPGI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14/go.mod h1:VymhrMJUWs69D8u0/lZ7jSB6WgaG/NqHi3gX0aYf6U0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.8/go.mod h1:KcGkXFVU8U28qS4KvLEcPxytPZPBcRawaH2Pf/0jptE=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.8 h1:HhJYoES3zOz34yWEpGENqJvRVPqpmJyR3+AFg9ybhdY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14/go.mod h1:1ipeGBMAxZ0xcTm6y6paC2C/J6f6OO7LBODV9afuAyM= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.8/go.mod h1:JnA+hPWeYAVbDssp83tv+ysAG8lTfLVXvSsyKg/7xNA=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 h1:GMYy2EOWfzdP3wfVAGXBNKY5vK4K8vMET4sYOYltmqs= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 h1:GMYy2EOWfzdP3wfVAGXBNKY5vK4K8vMET4sYOYltmqs=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36/go.mod h1:gDhdAV6wL3PmPqBhiPbnlS447GoWs8HTTOYef9/9Inw= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36/go.mod h1:gDhdAV6wL3PmPqBhiPbnlS447GoWs8HTTOYef9/9Inw=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 h1:nAP2GYbfh8dd2zGZqFRSMlq+/F6cMPBUuCsGAMkN074= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 h1:nAP2GYbfh8dd2zGZqFRSMlq+/F6cMPBUuCsGAMkN074=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4/go.mod h1:LT10DsiGjLWh4GbjInf9LQejkYEhBgBCjLG5+lvk4EE= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4/go.mod h1:LT10DsiGjLWh4GbjInf9LQejkYEhBgBCjLG5+lvk4EE=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.8 h1:M6JI2aGFEzYxsF6CXIuRBnkge9Wf9a2xU39rNeXgu10=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.8/go.mod h1:Fw+MyTwlwjFsSTE31mH211Np+CUslml8mzc0AFEG09s=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 h1:qcLWgdhq45sDM9na4cvXax9dyLitn8EYBRl8Ak4XtG4= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 h1:qcLWgdhq45sDM9na4cvXax9dyLitn8EYBRl8Ak4XtG4=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17/go.mod h1:M+jkjBFZ2J6DJrjMv2+vkBbuht6kxJYtJiwoVgX4p4U= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17/go.mod h1:M+jkjBFZ2J6DJrjMv2+vkBbuht6kxJYtJiwoVgX4p4U=
github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0 h1:0reDqfEN+tB+sozj2r92Bep8MEwBZgtAXTND1Kk9OXg= github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0 h1:0reDqfEN+tB+sozj2r92Bep8MEwBZgtAXTND1Kk9OXg=
github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0/go.mod h1:kUklwasNoCn5YpyAqC/97r6dzTA1SRKJfKq16SXeoDU= github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0/go.mod h1:kUklwasNoCn5YpyAqC/97r6dzTA1SRKJfKq16SXeoDU=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 h1:0JPwLz1J+5lEOfy/g0SURC9cxhbQ1lIMHMa+AHZSzz0= github.com/aws/aws-sdk-go-v2/service/sso v1.29.4 h1:FTdEN9dtWPB0EOURNtDPmwGp6GGvMqRJCAihkSl/1No=
github.com/aws/aws-sdk-go-v2/service/sso v1.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= github.com/aws/aws-sdk-go-v2/service/sso v1.29.4/go.mod h1:mYubxV9Ff42fZH4kexj43gFPhgc/LyC7KqvUKt1watc=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 h1:OWs0/j2UYR5LOGi88sD5/lhN6TDLG6SfA7CqsQO9zF0= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.0 h1:I7ghctfGXrscr7r1Ga/mDqSJKm7Fkpl5Mwq79Z+rZqU=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.0/go.mod h1:Zo9id81XP6jbayIFWNuDpA6lMBWhsVy+3ou2jLa4JnA=
github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 h1:+LVB0xBqEgjQoqr9bGZbRzvg212B0f17JdflleJRNR4=
github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= github.com/aws/aws-sdk-go-v2/service/sts v1.38.5/go.mod h1:xoaxeqnnUaZjPjaICgIy5B+MHCSb/ZSOn4MvkFNOUA0=
github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M=
github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0=
@@ -621,8 +619,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f h1:Br4SaUL3dnVopKKNhDavCLgehw60jdtl/sIxdfzmVts= github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7 h1:ZzG/gCclEit9w0QUfQt9GURcOycAIGcsQAhY1u0AEX0=
github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU= github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o= github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg= github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg=
github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGrHj3GdFbvsMzUT7eusgii9PKf9L1ZaXDDbY= github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGrHj3GdFbvsMzUT7eusgii9PKf9L1ZaXDDbY=
@@ -637,8 +635,8 @@ github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfU
github.com/grafana/grafana-app-sdk v0.48.7/go.mod h1:DWsaaH39ZMHwSOSoUBaeW8paMrRaYsjRYlLwCJYd78k= github.com/grafana/grafana-app-sdk v0.48.7/go.mod h1:DWsaaH39ZMHwSOSoUBaeW8paMrRaYsjRYlLwCJYd78k=
github.com/grafana/grafana-app-sdk/logging v0.48.7 h1:Oa5qg473gka5+W/WQk61Xbw4YdAv+wV2Z4bJtzeCaQw= github.com/grafana/grafana-app-sdk/logging v0.48.7 h1:Oa5qg473gka5+W/WQk61Xbw4YdAv+wV2Z4bJtzeCaQw=
github.com/grafana/grafana-app-sdk/logging v0.48.7/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana-app-sdk/logging v0.48.7/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU=
github.com/grafana/grafana-aws-sdk v1.4.2 h1:GrUEoLbs46r8rG/GZL4L2b63Bo+rkIYKdtCT7kT5KkM= github.com/grafana/grafana-aws-sdk v1.3.0 h1:/bfJzP93rCel1GbWoRSq0oUo424MZXt8jAp2BK9w8tM=
github.com/grafana/grafana-aws-sdk v1.4.2/go.mod h1:1qnZdYs6gQzxxF0dDodaE7Rn9fiMzuhwvtaAZ7ySnhY= github.com/grafana/grafana-aws-sdk v1.3.0/go.mod h1:VGycF0JkCGKND2O5je1ucOqPJ0ZNhZYzV3c2bNBAaGk=
github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 h1:FFcEA01tW+SmuJIuDbHOdgUBL+d7DPrZ2N4zwzPhfGk= github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 h1:FFcEA01tW+SmuJIuDbHOdgUBL+d7DPrZ2N4zwzPhfGk=
github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1/go.mod h1:Oi4anANlCuTCc66jCyqIzfVbgLXFll8Wja+Y4vfANlc= github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1/go.mod h1:Oi4anANlCuTCc66jCyqIzfVbgLXFll8Wja+Y4vfANlc=
github.com/grafana/grafana-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad0a5JpEL4mH9ry7Ws= github.com/grafana/grafana-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad0a5JpEL4mH9ry7Ws=
@@ -655,8 +653,8 @@ github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasn
github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU=
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248=
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk=
github.com/grafana/sqlds/v5 v5.0.3 h1:+yUMUxfa0WANQsmS9xtTFSRX1Q55Iv1B9EjlrW4VlBU= github.com/grafana/sqlds/v4 v4.2.7 h1:sFQhsS7DBakNMdxa++yOfJ9BVvkZwFJ0B95o57K0/XA=
github.com/grafana/sqlds/v5 v5.0.3/go.mod h1:GKeTTiC+GeR1X0z3f0Iee+hZnNgN62uQpj5XVMx5Uew= github.com/grafana/sqlds/v4 v4.2.7/go.mod h1:BQRjUG8rOqrBI4NAaeoWrIMuoNgfi8bdhCJ+5cgEfLU=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o=
@@ -28,7 +28,7 @@ type check struct {
PluginStore pluginstore.Store PluginStore pluginstore.Store
PluginContextProvider PluginContextProvider PluginContextProvider PluginContextProvider
PluginClient plugins.Client PluginClient plugins.Client
PluginRepo checks.PluginInfoGetter PluginRepo repo.Service
GrafanaVersion string GrafanaVersion string
pluginCanBeInstalledCache map[string]bool pluginCanBeInstalledCache map[string]bool
pluginExistsCacheMu sync.RWMutex pluginExistsCacheMu sync.RWMutex
@@ -39,7 +39,7 @@ func New(
pluginStore pluginstore.Store, pluginStore pluginstore.Store,
pluginContextProvider PluginContextProvider, pluginContextProvider PluginContextProvider,
pluginClient plugins.Client, pluginClient plugins.Client,
pluginRepo checks.PluginInfoGetter, pluginRepo repo.Service,
grafanaVersion string, grafanaVersion string,
) checks.Check { ) checks.Check {
return &check{ return &check{
@@ -15,7 +15,7 @@ import (
type missingPluginStep struct { type missingPluginStep struct {
PluginStore pluginstore.Store PluginStore pluginstore.Store
PluginRepo checks.PluginInfoGetter PluginRepo repo.Service
GrafanaVersion string GrafanaVersion string
} }
-8
View File
@@ -5,7 +5,6 @@ import (
"github.com/grafana/grafana-app-sdk/logging" "github.com/grafana/grafana-app-sdk/logging"
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
"github.com/grafana/grafana/pkg/plugins/repo"
) )
// Check returns metadata about the check being executed and the list of Steps // Check returns metadata about the check being executed and the list of Steps
@@ -38,10 +37,3 @@ type Step interface {
// Run executes the step for an item and returns a report // Run executes the step for an item and returns a report
Run(ctx context.Context, log logging.Logger, obj *advisorv0alpha1.CheckSpec, item any) ([]advisorv0alpha1.CheckReportFailure, error) Run(ctx context.Context, log logging.Logger, obj *advisorv0alpha1.CheckSpec, item any) ([]advisorv0alpha1.CheckReportFailure, error)
} }
// PluginInfoGetter is a minimal interface for retrieving plugin information from a repository.
// It contains only the GetPluginsInfo method used by plugincheck and datasourcecheck.
type PluginInfoGetter interface {
// GetPluginsInfo will return a list of plugins from grafana.com/api/plugins.
GetPluginsInfo(ctx context.Context, options repo.GetPluginsInfoOptions, compatOpts repo.CompatOpts) ([]repo.PluginInfo, error)
}
@@ -17,7 +17,7 @@ const (
func New( func New(
pluginStore pluginstore.Store, pluginStore pluginstore.Store,
pluginRepo checks.PluginInfoGetter, pluginRepo repo.Service,
updateChecker pluginchecker.PluginUpdateChecker, updateChecker pluginchecker.PluginUpdateChecker,
pluginErrorResolver plugins.ErrorResolver, pluginErrorResolver plugins.ErrorResolver,
grafanaVersion string, grafanaVersion string,
@@ -33,7 +33,7 @@ func New(
type check struct { type check struct {
PluginStore pluginstore.Store PluginStore pluginstore.Store
PluginRepo checks.PluginInfoGetter PluginRepo repo.Service
updateChecker pluginchecker.PluginUpdateChecker updateChecker pluginchecker.PluginUpdateChecker
pluginErrorResolver plugins.ErrorResolver pluginErrorResolver plugins.ErrorResolver
GrafanaVersion string GrafanaVersion string
+1 -1
View File
@@ -4,7 +4,7 @@ go 1.25.5
require ( require (
github.com/go-kit/log v0.2.1 github.com/go-kit/log v0.2.1
github.com/grafana/alerting v0.0.0-20260112172717-98a49ed9557f github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4
github.com/grafana/grafana-app-sdk v0.48.7 github.com/grafana/grafana-app-sdk v0.48.7
github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana-app-sdk/logging v0.48.7
+2 -2
View File
@@ -243,8 +243,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/grafana/alerting v0.0.0-20260112172717-98a49ed9557f h1:3bXOyht68qkfvD6Y8z8XoenFbytSSOIkr/s+AqRzj0o= github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7 h1:ZzG/gCclEit9w0QUfQt9GURcOycAIGcsQAhY1u0AEX0=
github.com/grafana/alerting v0.0.0-20260112172717-98a49ed9557f/go.mod h1:Ji0SfJChcwjgq8ljy6Y5CcYfHfAYKXjKYeysOoDS/6s= github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 h1:jSojuc7njleS3UOz223WDlXOinmuLAIPI0z2vtq8EgI= github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 h1:jSojuc7njleS3UOz223WDlXOinmuLAIPI0z2vtq8EgI=
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4/go.mod h1:VahT+GtfQIM+o8ht2StR6J9g+Ef+C2Vokh5uuSmOD/4= github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4/go.mod h1:VahT+GtfQIM+o8ht2StR6J9g+Ef+C2Vokh5uuSmOD/4=
github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo=
@@ -31,10 +31,6 @@ const (
maxLimit = 1000 maxLimit = 1000
Namespace = "grafana" Namespace = "grafana"
Subsystem = "alerting" Subsystem = "alerting"
// LogQL field path for alert rule UID after JSON parsing.
// Loki flattens nested JSON fields with underscores: alert.labels.__alert_rule_uid__ -> alert_labels___alert_rule_uid__
lokiAlertRuleUIDField = "alert_labels___alert_rule_uid__"
) )
var ( var (
@@ -115,13 +111,13 @@ func buildQuery(query Query) (string, error) {
fmt.Sprintf(`%s=%q`, historian.LabelFrom, historian.LabelFromValue), fmt.Sprintf(`%s=%q`, historian.LabelFrom, historian.LabelFromValue),
} }
logql := fmt.Sprintf(`{%s} | json`, strings.Join(selectors, `,`)) if query.RuleUID != nil {
selectors = append(selectors,
// Add ruleUID filter as JSON line filter if specified. fmt.Sprintf(`%s=%q`, historian.LabelRuleUID, *query.RuleUID))
if query.RuleUID != nil && *query.RuleUID != "" {
logql += fmt.Sprintf(` | %s = %q`, lokiAlertRuleUIDField, *query.RuleUID)
} }
logql := fmt.Sprintf(`{%s} | json`, strings.Join(selectors, `,`))
// Add receiver filter if specified. // Add receiver filter if specified.
if query.Receiver != nil && *query.Receiver != "" { if query.Receiver != nil && *query.Receiver != "" {
logql += fmt.Sprintf(` | receiver = %q`, *query.Receiver) logql += fmt.Sprintf(` | receiver = %q`, *query.Receiver)
@@ -215,13 +211,16 @@ func parseLokiEntry(s lokiclient.Sample) (Entry, error) {
groupLabels = make(map[string]string) groupLabels = make(map[string]string)
} }
alerts := []EntryAlert{{ alerts := make([]EntryAlert, len(lokiEntry.Alerts))
Status: lokiEntry.Alert.Status, for i, a := range lokiEntry.Alerts {
Labels: lokiEntry.Alert.Labels, alerts[i] = EntryAlert{
Annotations: lokiEntry.Alert.Annotations, Status: a.Status,
StartsAt: lokiEntry.Alert.StartsAt, Labels: a.Labels,
EndsAt: lokiEntry.Alert.EndsAt, Annotations: a.Annotations,
}} StartsAt: a.StartsAt,
EndsAt: a.EndsAt,
}
}
return Entry{ return Entry{
Timestamp: s.T, Timestamp: s.T,
@@ -7,7 +7,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/grafana/alerting/models"
"github.com/grafana/alerting/notify/historian" "github.com/grafana/alerting/notify/historian"
"github.com/grafana/alerting/notify/historian/lokiclient" "github.com/grafana/alerting/notify/historian/lokiclient"
"github.com/grafana/grafana-app-sdk/logging" "github.com/grafana/grafana-app-sdk/logging"
@@ -134,8 +133,9 @@ func TestBuildQuery(t *testing.T) {
query: Query{ query: Query{
RuleUID: stringPtr("test-rule-uid"), RuleUID: stringPtr("test-rule-uid"),
}, },
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid"`, expected: fmt.Sprintf(`{%s=%q,%s=%q} | json`,
historian.LabelFrom, historian.LabelFromValue), historian.LabelFrom, historian.LabelFromValue,
historian.LabelRuleUID, "test-rule-uid"),
}, },
{ {
name: "query with receiver filter", name: "query with receiver filter",
@@ -143,8 +143,9 @@ func TestBuildQuery(t *testing.T) {
RuleUID: stringPtr("test-rule-uid"), RuleUID: stringPtr("test-rule-uid"),
Receiver: stringPtr("email-receiver"), Receiver: stringPtr("email-receiver"),
}, },
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | receiver = "email-receiver"`, expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | receiver = "email-receiver"`,
historian.LabelFrom, historian.LabelFromValue), historian.LabelFrom, historian.LabelFromValue,
historian.LabelRuleUID, "test-rule-uid"),
}, },
{ {
name: "query with status filter", name: "query with status filter",
@@ -152,8 +153,9 @@ func TestBuildQuery(t *testing.T) {
RuleUID: stringPtr("test-rule-uid"), RuleUID: stringPtr("test-rule-uid"),
Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusFiring), Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusFiring),
}, },
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | status = "firing"`, expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | status = "firing"`,
historian.LabelFrom, historian.LabelFromValue), historian.LabelFrom, historian.LabelFromValue,
historian.LabelRuleUID, "test-rule-uid"),
}, },
{ {
name: "query with success outcome filter", name: "query with success outcome filter",
@@ -161,8 +163,9 @@ func TestBuildQuery(t *testing.T) {
RuleUID: stringPtr("test-rule-uid"), RuleUID: stringPtr("test-rule-uid"),
Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess), Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess),
}, },
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | error = ""`, expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | error = ""`,
historian.LabelFrom, historian.LabelFromValue), historian.LabelFrom, historian.LabelFromValue,
historian.LabelRuleUID, "test-rule-uid"),
}, },
{ {
name: "query with error outcome filter", name: "query with error outcome filter",
@@ -170,8 +173,9 @@ func TestBuildQuery(t *testing.T) {
RuleUID: stringPtr("test-rule-uid"), RuleUID: stringPtr("test-rule-uid"),
Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeError), Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeError),
}, },
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | error != ""`, expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | error != ""`,
historian.LabelFrom, historian.LabelFromValue), historian.LabelFrom, historian.LabelFromValue,
historian.LabelRuleUID, "test-rule-uid"),
}, },
{ {
name: "query with many filters", name: "query with many filters",
@@ -181,8 +185,9 @@ func TestBuildQuery(t *testing.T) {
Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusResolved), Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusResolved),
Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess), Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess),
}, },
expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | receiver = "email-receiver" | status = "resolved" | error = ""`, expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | receiver = "email-receiver" | status = "resolved" | error = ""`,
historian.LabelFrom, historian.LabelFromValue), historian.LabelFrom, historian.LabelFromValue,
historian.LabelRuleUID, "test-rule-uid"),
}, },
{ {
name: "query with group label matcher", name: "query with group label matcher",
@@ -272,19 +277,19 @@ func TestParseLokiEntry(t *testing.T) {
GroupLabels: map[string]string{ GroupLabels: map[string]string{
"alertname": "test-alert", "alertname": "test-alert",
}, },
Alert: historian.NotificationHistoryLokiEntryAlert{ Alerts: []historian.NotificationHistoryLokiEntryAlert{
Status: "firing", {
Labels: map[string]string{ Status: "firing",
"severity": "critical", Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Test alert",
},
StartsAt: now,
EndsAt: now.Add(1 * time.Hour),
}, },
Annotations: map[string]string{
"summary": "Test alert",
},
StartsAt: now,
EndsAt: now.Add(1 * time.Hour),
}, },
AlertIndex: 0,
AlertCount: 1,
Retry: false, Retry: false,
Duration: 100, Duration: 100,
PipelineTime: now, PipelineTime: now,
@@ -330,9 +335,7 @@ func TestParseLokiEntry(t *testing.T) {
Error: "notification failed", Error: "notification failed",
GroupKey: "key:thing", GroupKey: "key:thing",
GroupLabels: map[string]string{}, GroupLabels: map[string]string{},
Alert: historian.NotificationHistoryLokiEntryAlert{}, Alerts: []historian.NotificationHistoryLokiEntryAlert{},
AlertIndex: 0,
AlertCount: 1,
PipelineTime: now, PipelineTime: now,
}), }),
}, },
@@ -344,7 +347,7 @@ func TestParseLokiEntry(t *testing.T) {
Outcome: OutcomeError, Outcome: OutcomeError,
GroupKey: "key:thing", GroupKey: "key:thing",
GroupLabels: map[string]string{}, GroupLabels: map[string]string{},
Alerts: []EntryAlert{{}}, Alerts: []EntryAlert{},
Error: stringPtr("notification failed"), Error: stringPtr("notification failed"),
PipelineTime: now, PipelineTime: now,
}, },
@@ -362,7 +365,7 @@ func TestParseLokiEntry(t *testing.T) {
Status: Status("firing"), Status: Status("firing"),
Outcome: OutcomeSuccess, Outcome: OutcomeSuccess,
GroupLabels: map[string]string{}, GroupLabels: map[string]string{},
Alerts: []EntryAlert{{}}, Alerts: []EntryAlert{},
PipelineTime: now, PipelineTime: now,
}, },
}, },
@@ -445,9 +448,7 @@ func TestLokiReader_RunQuery(t *testing.T) {
Receiver: "receiver-1", Receiver: "receiver-1",
Status: "firing", Status: "firing",
GroupLabels: map[string]string{}, GroupLabels: map[string]string{},
Alert: historian.NotificationHistoryLokiEntryAlert{}, Alerts: []historian.NotificationHistoryLokiEntryAlert{},
AlertIndex: 0,
AlertCount: 1,
PipelineTime: now, PipelineTime: now,
}), }),
}, },
@@ -458,9 +459,7 @@ func TestLokiReader_RunQuery(t *testing.T) {
Receiver: "receiver-3", Receiver: "receiver-3",
Status: "firing", Status: "firing",
GroupLabels: map[string]string{}, GroupLabels: map[string]string{},
Alert: historian.NotificationHistoryLokiEntryAlert{}, Alerts: []historian.NotificationHistoryLokiEntryAlert{},
AlertIndex: 0,
AlertCount: 1,
PipelineTime: now, PipelineTime: now,
}), }),
}, },
@@ -475,9 +474,7 @@ func TestLokiReader_RunQuery(t *testing.T) {
Receiver: "receiver-2", Receiver: "receiver-2",
Status: "firing", Status: "firing",
GroupLabels: map[string]string{}, GroupLabels: map[string]string{},
Alert: historian.NotificationHistoryLokiEntryAlert{}, Alerts: []historian.NotificationHistoryLokiEntryAlert{},
AlertIndex: 0,
AlertCount: 1,
PipelineTime: now, PipelineTime: now,
}), }),
}, },
@@ -549,19 +546,19 @@ func createMockLokiResponse(timestamp time.Time) lokiclient.QueryRes {
GroupLabels: map[string]string{ GroupLabels: map[string]string{
"alertname": "test-alert", "alertname": "test-alert",
}, },
Alert: historian.NotificationHistoryLokiEntryAlert{ Alerts: []historian.NotificationHistoryLokiEntryAlert{
Status: "firing", {
Labels: map[string]string{ Status: "firing",
"severity": "critical", Labels: map[string]string{
"severity": "critical",
},
Annotations: map[string]string{
"summary": "Test alert",
},
StartsAt: timestamp,
EndsAt: timestamp.Add(1 * time.Hour),
}, },
Annotations: map[string]string{
"summary": "Test alert",
},
StartsAt: timestamp,
EndsAt: timestamp.Add(1 * time.Hour),
}, },
AlertIndex: 0,
AlertCount: 1,
Retry: false, Retry: false,
Duration: 100, Duration: 100,
PipelineTime: timestamp, PipelineTime: timestamp,
@@ -590,19 +587,10 @@ func createLokiEntryJSONWithNilLabels(t *testing.T, timestamp time.Time) string
"status": "firing", "status": "firing",
"error": "", "error": "",
"groupLabels": null, "groupLabels": null,
"alert": {}, "alerts": [],
"alertIndex": 0,
"alertCount": 1,
"retry": false, "retry": false,
"duration": 0, "duration": 0,
"pipelineTime": "%s" "pipelineTime": "%s"
}`, timestamp.Format(time.RFC3339Nano)) }`, timestamp.Format(time.RFC3339Nano))
return jsonStr return jsonStr
} }
func TestRuleUIDLabelConstant(t *testing.T) {
// Verify that models.RuleUIDLabel has the expected value.
// If this changes in the alerting module, our LogQL field path constant will be incorrect
// and filtering for a single alert rule by its UID will break.
assert.Equal(t, "__alert_rule_uid__", models.RuleUIDLabel)
}
@@ -1,9 +1,6 @@
package v0alpha1 package v0alpha1
TemplateKind: *"grafana" | "mimir"
TemplateGroupSpec: { TemplateGroupSpec: {
title: string title: string
content: string content: string
kind: TemplateKind
} }
@@ -2,24 +2,13 @@
package v0alpha1 package v0alpha1
// +k8s:openapi-gen=true
type TemplateGroupTemplateKind string
const (
TemplateGroupTemplateKindGrafana TemplateGroupTemplateKind = "grafana"
TemplateGroupTemplateKindMimir TemplateGroupTemplateKind = "mimir"
)
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
type TemplateGroupSpec struct { type TemplateGroupSpec struct {
Title string `json:"title"` Title string `json:"title"`
Content string `json:"content"` Content string `json:"content"`
Kind TemplateGroupTemplateKind `json:"kind"`
} }
// NewTemplateGroupSpec creates a new TemplateGroupSpec object. // NewTemplateGroupSpec creates a new TemplateGroupSpec object.
func NewTemplateGroupSpec() *TemplateGroupSpec { func NewTemplateGroupSpec() *TemplateGroupSpec {
return &TemplateGroupSpec{ return &TemplateGroupSpec{}
Kind: TemplateGroupTemplateKindGrafana,
}
} }
@@ -26,7 +26,7 @@ var (
rawSchemaRoutingTreev0alpha1 = []byte(`{"Matcher":{"additionalProperties":false,"properties":{"label":{"type":"string"},"type":{"enum":["=","!=","=~","!~"],"type":"string"},"value":{"type":"string"}},"required":["type","label","value"],"type":"object"},"Route":{"additionalProperties":false,"properties":{"active_time_intervals":{"items":{"type":"string"},"type":"array"},"continue":{"type":"boolean"},"group_by":{"items":{"type":"string"},"type":"array"},"group_interval":{"type":"string"},"group_wait":{"type":"string"},"matchers":{"items":{"$ref":"#/components/schemas/Matcher"},"type":"array"},"mute_time_intervals":{"items":{"type":"string"},"type":"array"},"receiver":{"type":"string"},"repeat_interval":{"type":"string"},"routes":{"items":{"$ref":"#/components/schemas/Route"},"type":"array"}},"required":["continue"],"type":"object"},"RouteDefaults":{"additionalProperties":false,"properties":{"group_by":{"items":{"type":"string"},"type":"array"},"group_interval":{"type":"string"},"group_wait":{"type":"string"},"receiver":{"type":"string"},"repeat_interval":{"type":"string"}},"required":["receiver"],"type":"object"},"RoutingTree":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"defaults":{"$ref":"#/components/schemas/RouteDefaults"},"routes":{"items":{"$ref":"#/components/schemas/Route"},"type":"array"}},"required":["defaults","routes"],"type":"object"}}`) rawSchemaRoutingTreev0alpha1 = []byte(`{"Matcher":{"additionalProperties":false,"properties":{"label":{"type":"string"},"type":{"enum":["=","!=","=~","!~"],"type":"string"},"value":{"type":"string"}},"required":["type","label","value"],"type":"object"},"Route":{"additionalProperties":false,"properties":{"active_time_intervals":{"items":{"type":"string"},"type":"array"},"continue":{"type":"boolean"},"group_by":{"items":{"type":"string"},"type":"array"},"group_interval":{"type":"string"},"group_wait":{"type":"string"},"matchers":{"items":{"$ref":"#/components/schemas/Matcher"},"type":"array"},"mute_time_intervals":{"items":{"type":"string"},"type":"array"},"receiver":{"type":"string"},"repeat_interval":{"type":"string"},"routes":{"items":{"$ref":"#/components/schemas/Route"},"type":"array"}},"required":["continue"],"type":"object"},"RouteDefaults":{"additionalProperties":false,"properties":{"group_by":{"items":{"type":"string"},"type":"array"},"group_interval":{"type":"string"},"group_wait":{"type":"string"},"receiver":{"type":"string"},"repeat_interval":{"type":"string"}},"required":["receiver"],"type":"object"},"RoutingTree":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"defaults":{"$ref":"#/components/schemas/RouteDefaults"},"routes":{"items":{"$ref":"#/components/schemas/Route"},"type":"array"}},"required":["defaults","routes"],"type":"object"}}`)
versionSchemaRoutingTreev0alpha1 app.VersionSchema versionSchemaRoutingTreev0alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaRoutingTreev0alpha1, &versionSchemaRoutingTreev0alpha1) _ = json.Unmarshal(rawSchemaRoutingTreev0alpha1, &versionSchemaRoutingTreev0alpha1)
rawSchemaTemplateGroupv0alpha1 = []byte(`{"TemplateGroup":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"TemplateKind":{"enum":["grafana","mimir"],"type":"string"},"spec":{"additionalProperties":false,"properties":{"content":{"type":"string"},"kind":{"$ref":"#/components/schemas/TemplateKind","default":"grafana"},"title":{"type":"string"}},"required":["title","content","kind"],"type":"object"}}`) rawSchemaTemplateGroupv0alpha1 = []byte(`{"TemplateGroup":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"content":{"type":"string"},"title":{"type":"string"}},"required":["title","content"],"type":"object"}}`)
versionSchemaTemplateGroupv0alpha1 app.VersionSchema versionSchemaTemplateGroupv0alpha1 app.VersionSchema
_ = json.Unmarshal(rawSchemaTemplateGroupv0alpha1, &versionSchemaTemplateGroupv0alpha1) _ = json.Unmarshal(rawSchemaTemplateGroupv0alpha1, &versionSchemaTemplateGroupv0alpha1)
rawSchemaTimeIntervalv0alpha1 = []byte(`{"Interval":{"additionalProperties":false,"properties":{"days_of_month":{"items":{"type":"string"},"type":"array"},"location":{"type":"string"},"months":{"items":{"type":"string"},"type":"array"},"times":{"items":{"$ref":"#/components/schemas/TimeRange"},"type":"array"},"weekdays":{"items":{"type":"string"},"type":"array"},"years":{"items":{"type":"string"},"type":"array"}},"type":"object"},"TimeInterval":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"TimeRange":{"additionalProperties":false,"properties":{"end_time":{"type":"string"},"start_time":{"type":"string"}},"required":["start_time","end_time"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"name":{"type":"string"},"time_intervals":{"items":{"$ref":"#/components/schemas/Interval"},"type":"array"}},"required":["name","time_intervals"],"type":"object"}}`) rawSchemaTimeIntervalv0alpha1 = []byte(`{"Interval":{"additionalProperties":false,"properties":{"days_of_month":{"items":{"type":"string"},"type":"array"},"location":{"type":"string"},"months":{"items":{"type":"string"},"type":"array"},"times":{"items":{"$ref":"#/components/schemas/TimeRange"},"type":"array"},"weekdays":{"items":{"type":"string"},"type":"array"},"years":{"items":{"type":"string"},"type":"array"}},"type":"object"},"TimeInterval":{"properties":{"spec":{"$ref":"#/components/schemas/spec"}},"required":["spec"]},"TimeRange":{"additionalProperties":false,"properties":{"end_time":{"type":"string"},"start_time":{"type":"string"}},"required":["start_time","end_time"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"name":{"type":"string"},"time_intervals":{"items":{"$ref":"#/components/schemas/Interval"},"type":"array"}},"required":["name","time_intervals"],"type":"object"}}`)
@@ -254,18 +254,8 @@ FieldConfig: {
// custom is specified by the FieldConfig field // custom is specified by the FieldConfig field
// in panel plugin schemas. // in panel plugin schemas.
custom?: {...} custom?: {...}
// Calculate min max per field
fieldMinMax?: bool
// How null values should be handled when calculating field stats
// "null" - Include null values, "connected" - Ignore nulls, "null as zero" - Treat nulls as zero
nullValueMode?: NullValueMode
} }
// How null values should be handled
NullValueMode: "null" | "connected" | "null as zero"
DynamicConfigValue: { DynamicConfigValue: {
id: string | *"" id: string | *""
value?: _ value?: _
@@ -942,7 +932,6 @@ CustomVariableSpec: {
skipUrlSync: bool | *false skipUrlSync: bool | *false
description?: string description?: string
allowCustomValue: bool | *true allowCustomValue: bool | *true
valuesFormat?: "csv" | "json"
} }
// Custom variable kind // Custom variable kind
@@ -250,18 +250,8 @@ FieldConfig: {
// custom is specified by the FieldConfig field // custom is specified by the FieldConfig field
// in panel plugin schemas. // in panel plugin schemas.
custom?: {...} custom?: {...}
// Calculate min max per field
fieldMinMax?: bool
// How null values should be handled when calculating field stats
// "null" - Include null values, "connected" - Ignore nulls, "null as zero" - Treat nulls as zero
nullValueMode?: NullValueMode
} }
// How null values should be handled
NullValueMode: "null" | "connected" | "null as zero"
DynamicConfigValue: { DynamicConfigValue: {
id: string | *"" id: string | *""
value?: _ value?: _
@@ -945,7 +935,6 @@ CustomVariableSpec: {
skipUrlSync: bool | *false skipUrlSync: bool | *false
description?: string description?: string
allowCustomValue: bool | *true allowCustomValue: bool | *true
valuesFormat?: "csv" | "json"
} }
// Custom variable kind // Custom variable kind
@@ -222,10 +222,8 @@ lineage: schemas: [{
// Optional field, if you want to extract part of a series name or metric node segment. // Optional field, if you want to extract part of a series name or metric node segment.
// Named capture groups can be used to separate the display text and value. // Named capture groups can be used to separate the display text and value.
regex?: string regex?: string
// Optional, indicates whether a custom type variable uses CSV or JSON to define its values // Determine whether regex applies to variable value or display text
valuesFormat?: "csv" | "json" | *"csv" regexApplyTo?: #VariableRegexApplyTo
// Determine whether regex applies to variable value or display text
regexApplyTo?: #VariableRegexApplyTo
// Additional static options for query variable // Additional static options for query variable
staticOptions?: [...#VariableOption] staticOptions?: [...#VariableOption]
// Ordering of static options in relation to options returned from data source for query variable // Ordering of static options in relation to options returned from data source for query variable
@@ -222,10 +222,8 @@ lineage: schemas: [{
// Optional field, if you want to extract part of a series name or metric node segment. // Optional field, if you want to extract part of a series name or metric node segment.
// Named capture groups can be used to separate the display text and value. // Named capture groups can be used to separate the display text and value.
regex?: string regex?: string
// Optional, indicates whether a custom type variable uses CSV or JSON to define its values // Determine whether regex applies to variable value or display text
valuesFormat?: "csv" | "json" | *"csv" regexApplyTo?: #VariableRegexApplyTo
// Determine whether regex applies to variable value or display text
regexApplyTo?: #VariableRegexApplyTo
// Additional static options for query variable // Additional static options for query variable
staticOptions?: [...#VariableOption] staticOptions?: [...#VariableOption]
// Ordering of static options in relation to options returned from data source for query variable // Ordering of static options in relation to options returned from data source for query variable
@@ -258,18 +258,8 @@ FieldConfig: {
// custom is specified by the FieldConfig field // custom is specified by the FieldConfig field
// in panel plugin schemas. // in panel plugin schemas.
custom?: {...} custom?: {...}
// Calculate min max per field
fieldMinMax?: bool
// How null values should be handled when calculating field stats
// "null" - Include null values, "connected" - Ignore nulls, "null as zero" - Treat nulls as zero
nullValueMode?: NullValueMode
} }
// How null values should be handled
NullValueMode: "null" | "connected" | "null as zero"
DynamicConfigValue: { DynamicConfigValue: {
id: string | *"" id: string | *""
value?: _ value?: _
@@ -946,7 +936,6 @@ CustomVariableSpec: {
skipUrlSync: bool | *false skipUrlSync: bool | *false
description?: string description?: string
allowCustomValue: bool | *true allowCustomValue: bool | *true
valuesFormat?: "csv" | "json"
} }
// Custom variable kind // Custom variable kind
@@ -419,11 +419,6 @@ type DashboardFieldConfig struct {
// custom is specified by the FieldConfig field // custom is specified by the FieldConfig field
// in panel plugin schemas. // in panel plugin schemas.
Custom map[string]interface{} `json:"custom,omitempty"` Custom map[string]interface{} `json:"custom,omitempty"`
// Calculate min max per field
FieldMinMax *bool `json:"fieldMinMax,omitempty"`
// How null values should be handled when calculating field stats
// "null" - Include null values, "connected" - Ignore nulls, "null as zero" - Treat nulls as zero
NullValueMode *DashboardNullValueMode `json:"nullValueMode,omitempty"`
} }
// NewDashboardFieldConfig creates a new DashboardFieldConfig object. // NewDashboardFieldConfig creates a new DashboardFieldConfig object.
@@ -750,16 +745,6 @@ func NewDashboardActionVariable() *DashboardActionVariable {
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
const DashboardActionVariableType = "string" const DashboardActionVariableType = "string"
// How null values should be handled
// +k8s:openapi-gen=true
type DashboardNullValueMode string
const (
DashboardNullValueModeNull DashboardNullValueMode = "null"
DashboardNullValueModeConnected DashboardNullValueMode = "connected"
DashboardNullValueModeNullAsZero DashboardNullValueMode = "null as zero"
)
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
type DashboardDynamicConfigValue struct { type DashboardDynamicConfigValue struct {
Id string `json:"id"` Id string `json:"id"`
@@ -1718,19 +1703,18 @@ func NewDashboardCustomVariableKind() *DashboardCustomVariableKind {
// Custom variable specification // Custom variable specification
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
type DashboardCustomVariableSpec struct { type DashboardCustomVariableSpec struct {
Name string `json:"name"` Name string `json:"name"`
Query string `json:"query"` Query string `json:"query"`
Current DashboardVariableOption `json:"current"` Current DashboardVariableOption `json:"current"`
Options []DashboardVariableOption `json:"options"` Options []DashboardVariableOption `json:"options"`
Multi bool `json:"multi"` Multi bool `json:"multi"`
IncludeAll bool `json:"includeAll"` IncludeAll bool `json:"includeAll"`
AllValue *string `json:"allValue,omitempty"` AllValue *string `json:"allValue,omitempty"`
Label *string `json:"label,omitempty"` Label *string `json:"label,omitempty"`
Hide DashboardVariableHide `json:"hide"` Hide DashboardVariableHide `json:"hide"`
SkipUrlSync bool `json:"skipUrlSync"` SkipUrlSync bool `json:"skipUrlSync"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
AllowCustomValue bool `json:"allowCustomValue"` AllowCustomValue bool `json:"allowCustomValue"`
ValuesFormat *DashboardCustomVariableSpecValuesFormat `json:"valuesFormat,omitempty"`
} }
// NewDashboardCustomVariableSpec creates a new DashboardCustomVariableSpec object. // NewDashboardCustomVariableSpec creates a new DashboardCustomVariableSpec object.
@@ -2114,14 +2098,6 @@ const (
DashboardQueryVariableSpecStaticOptionsOrderSorted DashboardQueryVariableSpecStaticOptionsOrder = "sorted" DashboardQueryVariableSpecStaticOptionsOrderSorted DashboardQueryVariableSpecStaticOptionsOrder = "sorted"
) )
// +k8s:openapi-gen=true
type DashboardCustomVariableSpecValuesFormat string
const (
DashboardCustomVariableSpecValuesFormatCsv DashboardCustomVariableSpecValuesFormat = "csv"
DashboardCustomVariableSpecValuesFormatJson DashboardCustomVariableSpecValuesFormat = "json"
)
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
type DashboardPanelKindOrLibraryPanelKind struct { type DashboardPanelKindOrLibraryPanelKind struct {
PanelKind *DashboardPanelKind `json:"PanelKind,omitempty"` PanelKind *DashboardPanelKind `json:"PanelKind,omitempty"`
@@ -1548,12 +1548,6 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardCustomVariableSpec(ref common.R
Format: "", Format: "",
}, },
}, },
"valuesFormat": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
}, },
Required: []string{"name", "query", "current", "options", "multi", "includeAll", "hide", "skipUrlSync", "allowCustomValue"}, Required: []string{"name", "query", "current", "options", "multi", "includeAll", "hide", "skipUrlSync", "allowCustomValue"},
}, },
@@ -2277,20 +2271,6 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref common.Referenc
}, },
}, },
}, },
"fieldMinMax": {
SchemaProps: spec.SchemaProps{
Description: "Calculate min max per field",
Type: []string{"boolean"},
Format: "",
},
},
"nullValueMode": {
SchemaProps: spec.SchemaProps{
Description: "How null values should be handled when calculating field stats \"null\" - Include null values, \"connected\" - Ignore nulls, \"null as zero\" - Treat nulls as zero",
Type: []string{"string"},
Format: "",
},
},
}, },
}, },
}, },
@@ -254,18 +254,8 @@ FieldConfig: {
// custom is specified by the FieldConfig field // custom is specified by the FieldConfig field
// in panel plugin schemas. // in panel plugin schemas.
custom?: {...} custom?: {...}
// Calculate min max per field
fieldMinMax?: bool
// How null values should be handled when calculating field stats
// "null" - Include null values, "connected" - Ignore nulls, "null as zero" - Treat nulls as zero
nullValueMode?: NullValueMode
} }
// How null values should be handled
NullValueMode: "null" | "connected" | "null as zero"
DynamicConfigValue: { DynamicConfigValue: {
id: string | *"" id: string | *""
value?: _ value?: _
@@ -949,7 +939,6 @@ CustomVariableSpec: {
skipUrlSync: bool | *false skipUrlSync: bool | *false
description?: string description?: string
allowCustomValue: bool | *true allowCustomValue: bool | *true
valuesFormat?: "csv" | "json"
} }
// Custom variable kind // Custom variable kind
@@ -423,11 +423,6 @@ type DashboardFieldConfig struct {
// custom is specified by the FieldConfig field // custom is specified by the FieldConfig field
// in panel plugin schemas. // in panel plugin schemas.
Custom map[string]interface{} `json:"custom,omitempty"` Custom map[string]interface{} `json:"custom,omitempty"`
// Calculate min max per field
FieldMinMax *bool `json:"fieldMinMax,omitempty"`
// How null values should be handled when calculating field stats
// "null" - Include null values, "connected" - Ignore nulls, "null as zero" - Treat nulls as zero
NullValueMode *DashboardNullValueMode `json:"nullValueMode,omitempty"`
} }
// NewDashboardFieldConfig creates a new DashboardFieldConfig object. // NewDashboardFieldConfig creates a new DashboardFieldConfig object.
@@ -754,16 +749,6 @@ func NewDashboardActionVariable() *DashboardActionVariable {
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
const DashboardActionVariableType = "string" const DashboardActionVariableType = "string"
// How null values should be handled
// +k8s:openapi-gen=true
type DashboardNullValueMode string
const (
DashboardNullValueModeNull DashboardNullValueMode = "null"
DashboardNullValueModeConnected DashboardNullValueMode = "connected"
DashboardNullValueModeNullAsZero DashboardNullValueMode = "null as zero"
)
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
type DashboardDynamicConfigValue struct { type DashboardDynamicConfigValue struct {
Id string `json:"id"` Id string `json:"id"`
@@ -1722,19 +1707,18 @@ func NewDashboardCustomVariableKind() *DashboardCustomVariableKind {
// Custom variable specification // Custom variable specification
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
type DashboardCustomVariableSpec struct { type DashboardCustomVariableSpec struct {
Name string `json:"name"` Name string `json:"name"`
Query string `json:"query"` Query string `json:"query"`
Current DashboardVariableOption `json:"current"` Current DashboardVariableOption `json:"current"`
Options []DashboardVariableOption `json:"options"` Options []DashboardVariableOption `json:"options"`
Multi bool `json:"multi"` Multi bool `json:"multi"`
IncludeAll bool `json:"includeAll"` IncludeAll bool `json:"includeAll"`
AllValue *string `json:"allValue,omitempty"` AllValue *string `json:"allValue,omitempty"`
Label *string `json:"label,omitempty"` Label *string `json:"label,omitempty"`
Hide DashboardVariableHide `json:"hide"` Hide DashboardVariableHide `json:"hide"`
SkipUrlSync bool `json:"skipUrlSync"` SkipUrlSync bool `json:"skipUrlSync"`
Description *string `json:"description,omitempty"` Description *string `json:"description,omitempty"`
AllowCustomValue bool `json:"allowCustomValue"` AllowCustomValue bool `json:"allowCustomValue"`
ValuesFormat *DashboardCustomVariableSpecValuesFormat `json:"valuesFormat,omitempty"`
} }
// NewDashboardCustomVariableSpec creates a new DashboardCustomVariableSpec object. // NewDashboardCustomVariableSpec creates a new DashboardCustomVariableSpec object.
@@ -2149,14 +2133,6 @@ const (
DashboardQueryVariableSpecStaticOptionsOrderSorted DashboardQueryVariableSpecStaticOptionsOrder = "sorted" DashboardQueryVariableSpecStaticOptionsOrderSorted DashboardQueryVariableSpecStaticOptionsOrder = "sorted"
) )
// +k8s:openapi-gen=true
type DashboardCustomVariableSpecValuesFormat string
const (
DashboardCustomVariableSpecValuesFormatCsv DashboardCustomVariableSpecValuesFormat = "csv"
DashboardCustomVariableSpecValuesFormatJson DashboardCustomVariableSpecValuesFormat = "json"
)
// +k8s:openapi-gen=true // +k8s:openapi-gen=true
type DashboardPanelKindOrLibraryPanelKind struct { type DashboardPanelKindOrLibraryPanelKind struct {
PanelKind *DashboardPanelKind `json:"PanelKind,omitempty"` PanelKind *DashboardPanelKind `json:"PanelKind,omitempty"`
@@ -1560,12 +1560,6 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardCustomVariableSpec(ref common.Re
Format: "", Format: "",
}, },
}, },
"valuesFormat": {
SchemaProps: spec.SchemaProps{
Type: []string{"string"},
Format: "",
},
},
}, },
Required: []string{"name", "query", "current", "options", "multi", "includeAll", "hide", "skipUrlSync", "allowCustomValue"}, Required: []string{"name", "query", "current", "options", "multi", "includeAll", "hide", "skipUrlSync", "allowCustomValue"},
}, },
@@ -2284,20 +2278,6 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardFieldConfig(ref common.Reference
}, },
}, },
}, },
"fieldMinMax": {
SchemaProps: spec.SchemaProps{
Description: "Calculate min max per field",
Type: []string{"boolean"},
Format: "",
},
},
"nullValueMode": {
SchemaProps: spec.SchemaProps{
Description: "How null values should be handled when calculating field stats \"null\" - Include null values, \"connected\" - Ignore nulls, \"null as zero\" - Treat nulls as zero",
Type: []string{"string"},
Format: "",
},
},
}, },
}, },
}, },
File diff suppressed because one or more lines are too long
@@ -180,15 +180,12 @@ func countAnnotationsV0V1(spec map[string]interface{}) int {
return 0 return 0
} }
// Handle both []interface{} (from JSON unmarshaling) and []map[string]interface{} (from programmatic creation) annotationList, ok := annotations["list"].([]interface{})
if annotationList, ok := annotations["list"].([]interface{}); ok { if !ok {
return len(annotationList) return 0
}
if annotationList, ok := annotations["list"].([]map[string]interface{}); ok {
return len(annotationList)
} }
return 0 return len(annotationList)
} }
// countLinksV0V1 counts dashboard links in v0alpha1 or v1beta1 dashboard spec // countLinksV0V1 counts dashboard links in v0alpha1 or v1beta1 dashboard spec
@@ -197,15 +194,12 @@ func countLinksV0V1(spec map[string]interface{}) int {
return 0 return 0
} }
// Handle both []interface{} (from JSON unmarshaling) and []map[string]interface{} (from programmatic creation) links, ok := spec["links"].([]interface{})
if links, ok := spec["links"].([]interface{}); ok { if !ok {
return len(links) return 0
}
if links, ok := spec["links"].([]map[string]interface{}); ok {
return len(links)
} }
return 0 return len(links)
} }
// countVariablesV0V1 counts template variables in v0alpha1 or v1beta1 dashboard spec // countVariablesV0V1 counts template variables in v0alpha1 or v1beta1 dashboard spec
@@ -219,15 +213,12 @@ func countVariablesV0V1(spec map[string]interface{}) int {
return 0 return 0
} }
// Handle both []interface{} (from JSON unmarshaling) and []map[string]interface{} (from programmatic creation) variableList, ok := templating["list"].([]interface{})
if variableList, ok := templating["list"].([]interface{}); ok { if !ok {
return len(variableList) return 0
}
if variableList, ok := templating["list"].([]map[string]interface{}); ok {
return len(variableList)
} }
return 0 return len(variableList)
} }
// collectStatsV0V1 collects statistics from v0alpha1 or v1beta1 dashboard // collectStatsV0V1 collects statistics from v0alpha1 or v1beta1 dashboard
@@ -85,20 +85,20 @@ func withConversionMetrics(sourceVersionAPI, targetVersionAPI string, conversion
// Only track schema versions for v0/v1 dashboards (v2+ info is redundant with API version) // Only track schema versions for v0/v1 dashboards (v2+ info is redundant with API version)
switch source := a.(type) { switch source := a.(type) {
case *dashv0.Dashboard: case *dashv0.Dashboard:
dashboardUID = source.Name dashboardUID = string(source.UID)
if source.Spec.Object != nil { if source.Spec.Object != nil {
sourceSchemaVersion = schemaversion.GetSchemaVersion(source.Spec.Object) sourceSchemaVersion = schemaversion.GetSchemaVersion(source.Spec.Object)
} }
case *dashv1.Dashboard: case *dashv1.Dashboard:
dashboardUID = source.Name dashboardUID = string(source.UID)
if source.Spec.Object != nil { if source.Spec.Object != nil {
sourceSchemaVersion = schemaversion.GetSchemaVersion(source.Spec.Object) sourceSchemaVersion = schemaversion.GetSchemaVersion(source.Spec.Object)
} }
case *dashv2alpha1.Dashboard: case *dashv2alpha1.Dashboard:
dashboardUID = source.Name dashboardUID = string(source.UID)
// Don't track schema version for v2+ (redundant with API version) // Don't track schema version for v2+ (redundant with API version)
case *dashv2beta1.Dashboard: case *dashv2beta1.Dashboard:
dashboardUID = source.Name dashboardUID = string(source.UID)
// Don't track schema version for v2+ (redundant with API version) // Don't track schema version for v2+ (redundant with API version)
} }
@@ -1,427 +0,0 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"type": "dashboard"
},
{
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations \u0026 Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"enable": true,
"filter": {
"exclude": false,
"ids": [
1
]
},
"iconColor": "red",
"name": "Red, only panel 1",
"target": {
"lines": 4,
"refId": "Anno",
"scenarioId": "annotations"
}
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"enable": true,
"filter": {
"exclude": true,
"ids": [
1
]
},
"iconColor": "yellow",
"name": "Yellow - all except 1",
"target": {
"lines": 5,
"refId": "Anno",
"scenarioId": "annotations"
}
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"enable": true,
"filter": {
"exclude": false,
"ids": [
3,
4
]
},
"iconColor": "dark-purple",
"name": "Purple only panel 3+4",
"target": {
"lines": 6,
"refId": "Anno",
"scenarioId": "annotations"
}
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 119,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel one",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel two",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 8
},
"id": 3,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel three",
"type": "timeseries"
},
{
"datasource": {
"type": "grafana-testdata-datasource"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 8
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"title": "Panel four",
"type": "timeseries"
}
],
"refresh": "",
"schemaVersion": 42,
"tags": [
"gdev",
"annotations"
],
"templating": {
"list": []
},
"time": {
"from": "now-30m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Annotation filtering",
"uid": "ed155665",
"weekStart": ""
}
@@ -219,7 +219,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -311,7 +312,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -490,7 +492,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -581,7 +584,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -672,7 +676,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -786,7 +791,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -900,7 +906,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -1015,7 +1022,8 @@
"value": 80 "value": 80
} }
] ]
} },
"unitScale": true
}, },
"overrides": [] "overrides": []
}, },
@@ -300,9 +300,15 @@
"y": 0 "y": 0
}, },
"id": 6, "id": 6,
"options": {}, "options": {
"content": "# Graph panel \u003e\u003e Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions", "code": {
"mode": "markdown", "language": "plaintext",
"showLineNumbers": false,
"showMiniMap": false
},
"content": "# Graph panel \u003e\u003e Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions",
"mode": "markdown"
},
"pluginVersion": "11.0.0-pre", "pluginVersion": "11.0.0-pre",
"targets": [ "targets": [
{ {

Some files were not shown because too many files have changed in this diff Show More