diff --git a/.citools/src/cog/go.mod b/.citools/src/cog/go.mod index 83bc319bb5e..6a2eab53809 100644 --- a/.citools/src/cog/go.mod +++ b/.citools/src/cog/go.mod @@ -10,7 +10,7 @@ require ( github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/proto v1.13.2 // indirect - github.com/expr-lang/expr v1.17.0 // indirect + github.com/expr-lang/expr v1.17.7 // indirect github.com/getkin/kin-openapi v0.132.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 30bba5db0ff..ec656436ee7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -24,7 +24,6 @@ /NOTICE.md @torkelo /README.md @grafana/docs-grafana /ROADMAP.md @torkelo -/SECURITY.md @grafana/security-team /SUPPORT.md @torkelo /WORKFLOW.md @torkelo /contribute/ @grafana/grafana-community-support @@ -85,6 +84,7 @@ # Git Sync frontend owned by frontend team as a whole. /apps/alerting/ @grafana/alerting-backend +/apps/quotas/ @grafana/grafana-search-and-storage /apps/dashboard/ @grafana/grafana-app-platform-squad @grafana/dashboards-squad /apps/folder/ @grafana/grafana-app-platform-squad /apps/playlist/ @grafana/grafana-app-platform-squad @@ -94,7 +94,6 @@ /apps/shorturl/ @grafana/sharing-squad /apps/secret/ @grafana/grafana-operator-experience-squad /apps/scope/ @grafana/grafana-operator-experience-squad -/apps/investigations/ @fcjack @matryer @svennergr /apps/advisor/ @grafana/plugins-platform-backend /apps/iam/ @grafana/access-squad /apps/sdk.mk @grafana/grafana-app-platform-squad @@ -207,7 +206,7 @@ /pkg/tests/apis/shorturl @grafana/sharing-squad /pkg/tests/api/correlations/ @grafana/datapro /pkg/tsdb/grafanads/ @grafana/grafana-backend-group -/pkg/tsdb/opentsdb/ @grafana/partner-datasources +/pkg/tsdb/opentsdb/ @grafana/oss-big-tent /pkg/util/ @grafana/grafana-backend-group /pkg/web/ @grafana/grafana-backend-group @@ -259,7 +258,7 @@ /devenv/dev-dashboards/dashboards.go @grafana/dataviz-squad /devenv/dev-dashboards/home.json @grafana/dataviz-squad /devenv/dev-dashboards/datasource-elasticsearch/ @grafana/partner-datasources -/devenv/dev-dashboards/datasource-opentsdb/ @grafana/partner-datasources +/devenv/dev-dashboards/datasource-opentsdb/ @grafana/oss-big-tent /devenv/dev-dashboards/datasource-influxdb/ @grafana/partner-datasources /devenv/dev-dashboards/datasource-mssql/ @grafana/partner-datasources /devenv/dev-dashboards/datasource-loki/ @grafana/plugins-platform-frontend @@ -306,7 +305,7 @@ /devenv/docker/blocks/mysql_exporter/ @grafana/oss-big-tent /devenv/docker/blocks/mysql_opendata/ @grafana/oss-big-tent /devenv/docker/blocks/mysql_tests/ @grafana/oss-big-tent -/devenv/docker/blocks/opentsdb/ @grafana/partner-datasources +/devenv/docker/blocks/opentsdb/ @grafana/oss-big-tent /devenv/docker/blocks/postgres/ @grafana/oss-big-tent /devenv/docker/blocks/postgres_tests/ @grafana/oss-big-tent /devenv/docker/blocks/prometheus/ @grafana/oss-big-tent @@ -425,6 +424,7 @@ 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 /e2e/ @grafana/grafana-frontend-platform +/e2e-playwright/alerting-suite/ @grafana/alerting-frontend /e2e-playwright/cloud-plugins-suite/ @grafana/partner-datasources /e2e-playwright/dashboard-new-layouts/ @grafana/dashboards-squad /e2e-playwright/dashboard-cujs/ @grafana/dashboards-squad @@ -500,7 +500,6 @@ i18next.config.ts @grafana/grafana-frontend-platform /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-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/graph-auto-migrate.spec.ts @grafana/dataviz-squad /e2e-playwright/various-suite/inspect-drawer.spec.ts @grafana/dashboards-squad @@ -519,7 +518,7 @@ i18next.config.ts @grafana/grafana-frontend-platform /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/verify-i18n.spec.ts @grafana/grafana-frontend-platform -/e2e-playwright/various-suite/visualization-suggestions.spec.ts @grafana/dashboards-squad +/e2e-playwright/various-suite/visualization-suggestions*.spec.ts @grafana/dataviz-squad /e2e-playwright/various-suite/perf-test.spec.ts @grafana/grafana-frontend-platform # Packages @@ -955,6 +954,7 @@ playwright.storybook.config.ts @grafana/grafana-frontend-platform /public/app/features/notifications/ @grafana/grafana-search-navigate-organise /public/app/features/org/ @grafana/grafana-search-navigate-organise /public/app/features/panel/ @grafana/dashboards-squad +/public/app/features/panel/components/VizTypePicker/VisualizationSuggestions.tsx @grafana/dataviz-squad /public/app/features/panel/suggestions/ @grafana/dataviz-squad /public/app/features/playlist/ @grafana/dashboards-squad /public/app/features/plugins/ @grafana/plugins-platform-frontend @@ -1099,7 +1099,7 @@ eslint-suppressions.json @grafanabot /public/app/plugins/datasource/mixed/ @grafana/dashboards-squad /public/app/plugins/datasource/mssql/ @grafana/partner-datasources /public/app/plugins/datasource/mysql/ @grafana/oss-big-tent -/public/app/plugins/datasource/opentsdb/ @grafana/partner-datasources +/public/app/plugins/datasource/opentsdb/ @grafana/oss-big-tent /public/app/plugins/datasource/grafana-postgresql-datasource/ @grafana/oss-big-tent /public/app/plugins/datasource/prometheus/ @grafana/oss-big-tent /public/app/plugins/datasource/cloud-monitoring/ @grafana/partner-datasources diff --git a/.github/actions/build-package/action.yml b/.github/actions/build-package/action.yml index dd5aaa13650..978c6645240 100644 --- a/.github/actions/build-package/action.yml +++ b/.github/actions/build-package/action.yml @@ -82,14 +82,6 @@ inputs: description: Docker registry of produced images default: docker.io required: false - ubuntu-base: - type: string - default: 'ubuntu:22.04' - required: false - alpine-base: - type: string - default: 'alpine:3.22' - required: false outputs: dist-dir: description: Directory where artifacts are placed @@ -134,13 +126,11 @@ runs: UBUNTU_TAG_FORMAT: ${{ inputs.docker-tag-format-ubuntu }} CHECKSUM: ${{ inputs.checksum }} VERIFY: ${{ inputs.verify }} - ALPINE_BASE: ${{ inputs.alpine-base }} - UBUNTU_BASE: ${{ inputs.ubuntu-base }} with: verb: run dagger-flags: --verbose=0 version: 0.18.8 - 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 + 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 - id: output shell: bash env: diff --git a/.github/actions/change-detection/action.yml b/.github/actions/change-detection/action.yml index 2c6b46606f4..1fd10ae5540 100644 --- a/.github/actions/change-detection/action.yml +++ b/.github/actions/change-detection/action.yml @@ -14,6 +14,9 @@ outputs: frontend: description: Whether the frontend or self has changed in any way 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: description: Whether the e2e tests or self have changed in any way value: ${{ steps.changed-files.outputs.e2e_any_changed == 'true' || @@ -95,9 +98,17 @@ runs: - 'nx.json' - 'tsconfig.json' - '.yarn/**' + - 'apps/dashboard/pkg/migration/**' + - '${{ inputs.self }}' + frontend_packages: + - '.github/actions/checkout/**' + - '.github/actions/change-detection/**' + - 'packages/**' + - './scripts/validate-npm-packages.sh' - '${{ inputs.self }}' e2e: - 'e2e/**' + - 'e2e-playwright/**' - '.github/actions/setup-enterprise/**' - '.github/actions/checkout/**' - 'emails/**' @@ -151,6 +162,8 @@ runs: echo " --> ${{ steps.changed-files.outputs.backend_all_changed_files }}" echo "Frontend: ${{ steps.changed-files.outputs.frontend_any_changed || 'true' }}" 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 " --> ${{ steps.changed-files.outputs.e2e_all_changed_files }}" echo " --> ${{ steps.changed-files.outputs.backend_all_changed_files }}" diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index 5762389f83b..92ffd43593c 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -4,8 +4,8 @@ description: Sets up a node.js environment with presets for the Grafana reposito runs: using: "composite" steps: - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version-file: '.nvmrc' cache: 'yarn' - cache-dependency-path: 'yarn.lock' \ No newline at end of file + cache-dependency-path: 'yarn.lock' diff --git a/.github/commands.json b/.github/commands.json index 29106576726..0db8a607b53 100644 --- a/.github/commands.json +++ b/.github/commands.json @@ -1226,5 +1226,13 @@ "addToProject": { "url": "https://github.com/orgs/grafana/projects/69" } + }, + { + "type": "label", + "name": "area/suggestions", + "action": "addToProject", + "addToProject": { + "url": "https://github.com/orgs/grafana/projects/56" + } } ] diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 79987600b9a..6356a793b36 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,7 +19,6 @@ updates: - "/apps/dashboard" - "/apps/folder" - "/apps/iam" - - "/apps/investigations" - "/apps/playlist" - "/apps/plugins" - "/apps/preferences" diff --git a/.github/pr-commands.json b/.github/pr-commands.json index 8b4472fe02a..bfff4753773 100644 --- a/.github/pr-commands.json +++ b/.github/pr-commands.json @@ -365,7 +365,9 @@ "type": "changedfiles", "matches": [ "public/app/plugins/panel/gauge/**/*", - "/packages/grafana-ui/src/components/Gauge/**/*" + "public/app/plugins/panel/radialbar/**/*", + "/packages/grafana-ui/src/components/Gauge/**/*", + "/packages/grafana-ui/src/components/RadialGauge/**/*" ], "action": "updateLabel", "addLabel": "area/panel/gauge" @@ -469,5 +471,15 @@ "addToProject": { "url": "https://github.com/orgs/grafana/projects/190" } + }, + { + "type": "changedfiles", + "matches": [ + "public/app/features/panel/suggestions/**/*", + "public/app/plugins/panel/**/suggestions.ts", + "packages/grafana-data/src/types/suggestions*" + ], + "action": "updateLabel", + "addLabel": "area/suggestions" } ] diff --git a/.github/workflows/add-to-whats-new.yml b/.github/workflows/add-to-whats-new.yml index a6a8bb8ea2e..c388d2799a4 100644 --- a/.github/workflows/add-to-whats-new.yml +++ b/.github/workflows/add-to-whats-new.yml @@ -1,11 +1,11 @@ -name: Add comment about adding a What's new note +name: Add comment about adding a What's new note for either what's new or breaking changes on: pull_request: types: [labeled] jobs: add-comment: - if: ${{ ! github.event.pull_request.head.repo.fork && contains(github.event.pull_request.labels.*.name, 'add to what''s new') }} + if: ${{ ! github.event.pull_request.head.repo.fork && (contains(github.event.pull_request.labels.*.name, 'add to what''s new') || contains(github.event.pull_request.labels.*.name, 'breaking change') || contains(github.event.pull_request.labels.*.name, 'levitate breaking change')) }} runs-on: ubuntu-latest permissions: pull-requests: write @@ -13,4 +13,4 @@ jobs: - uses: marocchino/sticky-pull-request-comment@773744901bac0e8cbb5a0dc842800d45e9b2b405 # v2.9.4 with: message: | - Since you've added the `Add to what's new` label, consider drafting a [What's new note](https://admin.grafana.com/content-admin/#/collections/whats-new/new) for this feature. + Since you've added the `What's New` or a breaking change label, consider drafting a [What's new note](https://admin.grafana.com/content-admin/#/collections/whats-new/new) for this feature. diff --git a/.github/workflows/auto-triager/labels.txt b/.github/workflows/auto-triager/labels.txt index 18ef2df93d8..451719ee0f7 100644 --- a/.github/workflows/auto-triager/labels.txt +++ b/.github/workflows/auto-triager/labels.txt @@ -85,6 +85,7 @@ area/scenes area/search area/security area/streaming +area/suggestions area/templating/repeating area/tooltip area/transformations diff --git a/.github/workflows/cleanup-branches.yml b/.github/workflows/cleanup-branches.yml index 7f4a6909e6e..7f359309cca 100644 --- a/.github/workflows/cleanup-branches.yml +++ b/.github/workflows/cleanup-branches.yml @@ -14,5 +14,5 @@ jobs: - uses: actions/checkout@v5 - uses: grafana/shared-workflows/actions/cleanup-branches@cleanup-branches/v0.2.1 with: - dry-run: true + dry-run: false max-date: "1 month ago" diff --git a/.github/workflows/ephemeral-instances-pr-comment.yml b/.github/workflows/ephemeral-instances-pr-comment.yml index d78b5b8f599..c116e43a443 100644 --- a/.github/workflows/ephemeral-instances-pr-comment.yml +++ b/.github/workflows/ephemeral-instances-pr-comment.yml @@ -33,6 +33,16 @@ jobs: GCOM_TOKEN=ephemeral-instances-bot:gcom-token REGISTRY=ephemeral-instances-bot:registry GCP_SA_ACCOUNT_KEY_BASE64=ephemeral-instances-bot:sa-key + # Secrets placed in the ci/common/ path in Vault + common_secrets: | + DOCKERHUB_USERNAME=dockerhub:username + DOCKERHUB_PASSWORD=dockerhub:password + + - name: Log in to Docker Hub to avoid unauthenticated image pull rate-limiting + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0 + with: + username: ${{ env.DOCKERHUB_USERNAME }} + password: ${{ env.DOCKERHUB_PASSWORD }} - name: Generate a GitHub app installation token id: generate_token diff --git a/.github/workflows/frontend-lint.yml b/.github/workflows/frontend-lint.yml index 02833d61149..539d57b1742 100644 --- a/.github/workflows/frontend-lint.yml +++ b/.github/workflows/frontend-lint.yml @@ -17,6 +17,7 @@ jobs: outputs: changed: ${{ steps.detect-changes.outputs.frontend }} prettier: ${{ steps.detect-changes.outputs.frontend == 'true' || steps.detect-changes.outputs.docs == 'true' }} + changed-frontend-packages: ${{ steps.detect-changes.outputs.frontend-packages }} steps: - uses: actions/checkout@v5 with: @@ -42,11 +43,8 @@ jobs: - uses: actions/checkout@v5 with: persist-credentials: false - - uses: actions/setup-node@v6 - with: - node-version-file: '.nvmrc' - cache: 'yarn' - cache-dependency-path: 'yarn.lock' + - name: Setup Node + uses: ./.github/actions/setup-node - run: yarn install --immutable --check-cache - run: yarn run prettier:check - run: yarn run lint @@ -63,11 +61,8 @@ jobs: - uses: actions/checkout@v5 with: persist-credentials: false - - uses: actions/setup-node@v6 - with: - node-version-file: '.nvmrc' - cache: 'yarn' - cache-dependency-path: 'yarn.lock' + - name: Setup Node + uses: ./.github/actions/setup-node - name: Setup Enterprise uses: ./.github/actions/setup-enterprise with: @@ -89,11 +84,8 @@ jobs: - uses: actions/checkout@v5 with: persist-credentials: false - - uses: actions/setup-node@v6 - with: - node-version-file: '.nvmrc' - cache: 'yarn' - cache-dependency-path: 'yarn.lock' + - name: Setup Node + uses: ./.github/actions/setup-node - run: yarn install --immutable --check-cache - run: yarn run typecheck lint-frontend-typecheck-enterprise: @@ -109,11 +101,8 @@ jobs: - uses: actions/checkout@v5 with: persist-credentials: false - - uses: actions/setup-node@v6 - with: - node-version-file: '.nvmrc' - cache: 'yarn' - cache-dependency-path: 'yarn.lock' + - name: Setup Node + uses: ./.github/actions/setup-node - name: Setup Enterprise uses: ./.github/actions/setup-enterprise with: @@ -133,11 +122,8 @@ jobs: - uses: actions/checkout@v5 with: persist-credentials: false - - uses: actions/setup-node@v6 - with: - node-version-file: '.nvmrc' - cache: 'yarn' - cache-dependency-path: 'yarn.lock' + - name: Setup Node + uses: ./.github/actions/setup-node - run: yarn install --immutable --check-cache - name: Generate API clients run: | @@ -164,11 +150,8 @@ jobs: - uses: actions/checkout@v5 with: persist-credentials: false - - uses: actions/setup-node@v6 - with: - node-version-file: '.nvmrc' - cache: 'yarn' - cache-dependency-path: 'yarn.lock' + - name: Setup Node + uses: ./.github/actions/setup-node - name: Setup Enterprise uses: ./.github/actions/setup-enterprise with: @@ -187,3 +170,26 @@ jobs: echo "${uncommited_error_message}" exit 1 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 diff --git a/.github/workflows/pr-patch-check-event.yml b/.github/workflows/pr-patch-check-event.yml index 2b30e0fa375..86a4ad64917 100644 --- a/.github/workflows/pr-patch-check-event.yml +++ b/.github/workflows/pr-patch-check-event.yml @@ -12,6 +12,7 @@ on: permissions: id-token: write contents: read + statuses: write # Since this is run on a pull request, we want to apply the patches intended for the # target branch onto the source branch, to verify compatibility before merging. diff --git a/.github/workflows/pr-patch-check.yml b/.github/workflows/pr-patch-check.yml index 52f75a05ff2..8a1f70174d7 100644 --- a/.github/workflows/pr-patch-check.yml +++ b/.github/workflows/pr-patch-check.yml @@ -29,6 +29,10 @@ permissions: # target branch onto the source branch, to verify compatibility before merging. jobs: dispatch-job: + # If the source is not from a fork then dispatch the job to the workflow. + # This will fail on forks when trying to broker a token, so instead, forks will create the required status and mark + # it as a success + if: ${{ ! github.event.pull_request.head.repo.fork }} env: HEAD_REF: ${{ inputs.head_ref }} BASE_REF: ${{ github.base_ref }} @@ -76,3 +80,20 @@ jobs: triggering_github_handle: SENDER } }) + dispatch-job-fork: + # If the source is from a fork then use the built-in workflow token to create the same status and unconditionally + # mark it as a success. + if: ${{ github.event.pull_request.head.repo.fork }} + permissions: + statuses: write + runs-on: ubuntu-latest + steps: + - name: Create status + uses: myrotvorets/set-commit-status-action@6d6905c99cd24a4a2cbccc720b62dc6ca5587141 + with: + token: ${{ github.token }} + sha: ${{ inputs.pr_commit_sha }} + repo: ${{ inputs.repo }} + status: success + context: "Test Patches (event)" + description: "Test Patches (event) on a fork" diff --git a/.github/workflows/release-comms.yml b/.github/workflows/release-comms.yml index 58ebe84dbc0..fb65b2a3eed 100644 --- a/.github/workflows/release-comms.yml +++ b/.github/workflows/release-comms.yml @@ -111,12 +111,13 @@ jobs: ownerRepo: 'grafana/grafana-enterprise' from: ${{ needs.setup.outputs.release_branch }} to: ${{ needs.create_next_release_branch_enterprise.outputs.branch }} - post_changelog_on_forum: - needs: setup - uses: grafana/grafana/.github/workflows/community-release.yml@main - with: - version: ${{ needs.setup.outputs.version }} - dry_run: ${{ needs.setup.outputs.dry_run == 'true' }} + # Removed this for now since it doesn't work + # post_changelog_on_forum: + # needs: setup + # uses: grafana/grafana/.github/workflows/community-release.yml@main + # with: + # version: ${{ needs.setup.outputs.version }} + # dry_run: ${{ needs.setup.outputs.dry_run == 'true' }} create_github_release: # a github release requires a git tag # The github-release action retrieves the changelog using the /repos/grafana/grafana/contents/CHANGELOG.md API diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index 999ccbc5e4a..9c332d0675a 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -90,6 +90,7 @@ jobs: with: persist-credentials: false ref: ${{ inputs.grafana_commit }} + fetch-depth: 2 # Need HEAD~1 for e2e-selectors change detection - name: Setup Node uses: ./.github/actions/setup-node @@ -127,3 +128,43 @@ jobs: env: NPM_TAG: ${{ steps.npm-tag.outputs.NPM_TAG }} run: ./scripts/publish-npm-packages.sh --dist-tag "$NPM_TAG" --registry 'https://registry.npmjs.org/' + + # Notify plugin-tools when e2e-selectors changes so it can update its bundled version + - name: Check for e2e-selectors changes + id: check-e2e-changes + run: | + CHANGES=$(git diff --name-only HEAD~1 HEAD -- packages/grafana-e2e-selectors | wc -l) + echo "changes=$CHANGES" >> "$GITHUB_OUTPUT" + if [ "$CHANGES" -gt 0 ]; then + echo "Detected $CHANGES file(s) changed in packages/grafana-e2e-selectors" + fi + + - name: Get Vault secrets + if: steps.check-e2e-changes.outputs.changes > 0 + id: vault-secrets + uses: grafana/shared-workflows/actions/get-vault-secrets@main + with: + repo_secrets: | + GRAFANA_DELIVERY_BOT_APP_PEM=delivery-bot-app:PRIVATE_KEY + + - name: Generate token for plugin-tools + if: steps.check-e2e-changes.outputs.changes > 0 + id: generate_token + uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a + with: + app_id: ${{ vars.DELIVERY_BOT_APP_ID }} + private_key: ${{ env.GRAFANA_DELIVERY_BOT_APP_PEM }} + repositories: '["plugin-tools"]' + permissions: '{"actions": "write"}' + + - name: Dispatch to plugin-tools + if: steps.check-e2e-changes.outputs.changes > 0 + env: + VERSION: ${{ inputs.version }} + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + echo "Dispatching bump-e2e-selectors workflow to grafana/plugin-tools with version $VERSION" + gh workflow run bump-e2e-selectors.yml \ + --repo grafana/plugin-tools \ + --ref main \ + --field version="$VERSION" diff --git a/.golangci.yml b/.golangci.yml index 3b7871662e2..069e88632ff 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,7 +3,7 @@ # Others can set up the YAML LSP manually, which supports schemas: https://github.com/redhat-developer/yaml-language-server # $schema: https://golangci-lint.run/jsonschema/golangci.jsonschema.json -version: "2" +version: '2' run: timeout: 15m concurrency: 10 @@ -67,14 +67,6 @@ linters: deny: - pkg: github.com/grafana/grafana/pkg 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: list-mode: lax files: @@ -83,6 +75,16 @@ linters: deny: - pkg: github.com/grafana/grafana/pkg desc: apps/playlist is not allowed to import grafana core + apps-dashboard: + list-mode: lax + files: + - ./apps/dashboard/* + - ./apps/dashboard/**/* + allow: + - github.com/grafana/grafana/pkg/apimachinery + deny: + - pkg: github.com/grafana/grafana/pkg + desc: apps/dashboard is not allowed to import grafana core apps-secret: list-mode: lax files: @@ -281,16 +283,16 @@ linters: text: G306 - linters: - gosec - text: "401" + text: '401' - linters: - gosec - text: "402" + text: '402' - linters: - gosec - text: "501" + text: '501' - linters: - gosec - text: "404" + text: '404' - linters: - errorlint text: non-wrapping format verb for fmt.Errorf diff --git a/.yarn/patches/@storybook-core-npm-8.6.15-a468a35170.patch b/.yarn/patches/@storybook-core-npm-8.6.15-a468a35170.patch new file mode 100644 index 00000000000..f3b7cb48e98 --- /dev/null +++ b/.yarn/patches/@storybook-core-npm-8.6.15-a468a35170.patch @@ -0,0 +1,13 @@ +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", diff --git a/CHANGELOG.md b/CHANGELOG.md index a4dfcb3171a..6bacfafdfd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,101 @@ + + +# 12.3.1 (2025-12-16) + +### Features and enhancements + +- **Alerting:** Update alerting dependency [#114259](https://github.com/grafana/grafana/pull/114259), [@moustafab](https://github.com/moustafab) +- **Azure:** Improved column handling in logs query builder [#114841](https://github.com/grafana/grafana/pull/114841), [@aangelisc](https://github.com/aangelisc) +- **Azure:** Include aggregate columns in logs builder [#114835](https://github.com/grafana/grafana/pull/114835), [@aangelisc](https://github.com/aangelisc) +- **Dependencies:** Bump Go to v1.25.5 [#114751](https://github.com/grafana/grafana/pull/114751), [@macabu](https://github.com/macabu) +- **Docs:** Clarify section title for repeating rows and tabs [#115346](https://github.com/grafana/grafana/pull/115346), [@imatwawana](https://github.com/imatwawana) +- **Plugins:** Add PluginContext to plugins when scenes is disabled [#115064](https://github.com/grafana/grafana/pull/115064), [@hugohaggmark](https://github.com/hugohaggmark) +- **QueryEditorRows:** Clear hideSeriesFrom override on query edit [#114628](https://github.com/grafana/grafana/pull/114628), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) + +### Bug fixes + +- **Azure:** Fix `dcount` aggregation [#114907](https://github.com/grafana/grafana/pull/114907), [@aangelisc](https://github.com/aangelisc) +- **Azure:** Fix `percentile` syntax [#114707](https://github.com/grafana/grafana/pull/114707), [@aangelisc](https://github.com/aangelisc) +- **Dashboards:** Fix empty space under time controls when a dashboard has a lot of variables [#114730](https://github.com/grafana/grafana/pull/114730), [@oscarkilhed](https://github.com/oscarkilhed) +- **Plugins:** Datasource breadcrumb link should link to settings tab [#113910](https://github.com/grafana/grafana/pull/113910), [@wbrowne](https://github.com/wbrowne) +- **Postgresql:** Fix variable interpolation logic when the variable has multiple values [#114876](https://github.com/grafana/grafana/pull/114876), [@itsmylife](https://github.com/itsmylife) + + + + +# 12.2.3 (2025-12-16) + +### Features and enhancements + +- **Alerting:** Update alerting dependency [#114256](https://github.com/grafana/grafana/pull/114256), [@moustafab](https://github.com/moustafab) +- **Azure:** Improved column handling in logs query builder [#114840](https://github.com/grafana/grafana/pull/114840), [@aangelisc](https://github.com/aangelisc) +- **Azure:** Include aggregate columns in logs builder [#114834](https://github.com/grafana/grafana/pull/114834), [@aangelisc](https://github.com/aangelisc) +- **Dependencies:** Bump Go to v1.25.5 [#114753](https://github.com/grafana/grafana/pull/114753), [@macabu](https://github.com/macabu) +- **Plugins:** Add PluginContext to plugins when scenes is disabled [#115063](https://github.com/grafana/grafana/pull/115063), [@hugohaggmark](https://github.com/hugohaggmark) +- **QueryEditorRows:** Clear hideSeriesFrom override on query edit [#114629](https://github.com/grafana/grafana/pull/114629), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) + +### Bug fixes + +- **Alerting:** Fix contact points issue [#115412](https://github.com/grafana/grafana/pull/115412), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Azure:** Fix `dcount` aggregation [#114906](https://github.com/grafana/grafana/pull/114906), [@aangelisc](https://github.com/aangelisc) +- **Azure:** Fix `percentile` syntax [#114706](https://github.com/grafana/grafana/pull/114706), [@aangelisc](https://github.com/aangelisc) +- **Postgresql:** Fix variable interpolation logic when the variable has multiple values [#114875](https://github.com/grafana/grafana/pull/114875), [@itsmylife](https://github.com/itsmylife) + + + + +# 12.1.5 (2025-12-16) + +### Features and enhancements + +- **Alerting:** Update alerting dependency [#114254](https://github.com/grafana/grafana/pull/114254), [@moustafab](https://github.com/moustafab) +- **Dependencies:** Bump Go to v1.25.5 [#114755](https://github.com/grafana/grafana/pull/114755), [@macabu](https://github.com/macabu) +- **Docs:** Clarify section title for repeating rows and tabs [#115344](https://github.com/grafana/grafana/pull/115344), [@imatwawana](https://github.com/imatwawana) +- **Plugins:** Add PluginContext to plugins when scenes is disabled [#115062](https://github.com/grafana/grafana/pull/115062), [@hugohaggmark](https://github.com/hugohaggmark) + +### Bug fixes + +- **Alerting:** Fix contact points issue [#115411](https://github.com/grafana/grafana/pull/115411), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Azure:** Fix `dcount` aggregation [#114905](https://github.com/grafana/grafana/pull/114905), [@aangelisc](https://github.com/aangelisc) +- **Azure:** Fix `percentile` syntax [#114705](https://github.com/grafana/grafana/pull/114705), [@aangelisc](https://github.com/aangelisc) +- **Postgresql:** Fix variable interpolation logic when the variable has multiple values [#114874](https://github.com/grafana/grafana/pull/114874), [@itsmylife](https://github.com/itsmylife) + + + + +# 12.0.8 (2025-12-16) + +### Features and enhancements + +- **Alerting:** Update alerting dependency [#114252](https://github.com/grafana/grafana/pull/114252), [@moustafab](https://github.com/moustafab) +- **Dependencies:** Bump Go to v1.25.5 [#114756](https://github.com/grafana/grafana/pull/114756), [@macabu](https://github.com/macabu) +- **Docs:** Clarify section title for repeating rows and tabs [#115343](https://github.com/grafana/grafana/pull/115343), [@imatwawana](https://github.com/imatwawana) +- **Plugins:** Add PluginContext to plugins when scenes is disabled [#115061](https://github.com/grafana/grafana/pull/115061), [@hugohaggmark](https://github.com/hugohaggmark) + +### Bug fixes + +- **Alerting:** Fix contact points issue [#115410](https://github.com/grafana/grafana/pull/115410), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Azure:** Fix `dcount` aggregation [#114904](https://github.com/grafana/grafana/pull/114904), [@aangelisc](https://github.com/aangelisc) +- **Azure:** Fix `percentile` syntax [#114704](https://github.com/grafana/grafana/pull/114704), [@aangelisc](https://github.com/aangelisc) +- **Postgresql:** Fix variable interpolation logic when the variable has multiple values [#114873](https://github.com/grafana/grafana/pull/114873), [@itsmylife](https://github.com/itsmylife) + + + + +# 11.6.9 (2025-12-16) + +### Features and enhancements + +- **Alerting:** Update alerting dependency [#114249](https://github.com/grafana/grafana/pull/114249), [@moustafab](https://github.com/moustafab) +- **Dependencies:** Bump Go to v1.25.5 [#114757](https://github.com/grafana/grafana/pull/114757), [@macabu](https://github.com/macabu) +- **PDFTables:** Dynamically shrink font to try and fit whole table in pdf page width (Enterprise) +- **Plugins:** Add PluginContext to plugins when scenes is disabled [#115060](https://github.com/grafana/grafana/pull/115060), [@hugohaggmark](https://github.com/hugohaggmark) + +### Bug fixes + +- **Alerting:** Fix contacts point issues [#115409](https://github.com/grafana/grafana/pull/115409), [@yuri-tceretian](https://github.com/yuri-tceretian) + + # 12.3.0 (2025-11-19) diff --git a/Dockerfile b/Dockerfile index d3f63dd0544..d3c2fc9ef5e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ ARG JS_SRC=js-builder # Dependabot cannot update dependencies listed in ARGs # By using FROM instructions we can delegate dependency updates to dependabot -FROM alpine:3.22.2 AS alpine-base +FROM alpine:3.23.0 AS alpine-base FROM ubuntu:22.04 AS ubuntu-base FROM golang:1.25.5-alpine AS go-builder-base FROM --platform=${JS_PLATFORM} node:24-alpine AS js-builder-base @@ -91,8 +91,10 @@ COPY pkg/storage/unified/resource pkg/storage/unified/resource COPY pkg/storage/unified/resourcepb pkg/storage/unified/resourcepb COPY pkg/storage/unified/apistore pkg/storage/unified/apistore COPY pkg/semconv pkg/semconv +COPY pkg/plugins pkg/plugins COPY pkg/aggregator pkg/aggregator COPY apps/playlist apps/playlist +COPY apps/quotas apps/quotas COPY apps/plugins apps/plugins COPY apps/shorturl apps/shorturl COPY apps/annotation apps/annotation @@ -102,7 +104,6 @@ COPY apps/collections apps/collections COPY apps/provisioning apps/provisioning COPY apps/secret apps/secret COPY apps/scope apps/scope -COPY apps/investigations apps/investigations COPY apps/logsdrilldown apps/logsdrilldown COPY apps/advisor apps/advisor COPY apps/dashboard apps/dashboard diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 42c58f9cd67..00000000000 --- a/SECURITY.md +++ /dev/null @@ -1,29 +0,0 @@ -# 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). diff --git a/apps/advisor/go.mod b/apps/advisor/go.mod index 941d8b9bc0f..c65d5dacdc5 100644 --- a/apps/advisor/go.mod +++ b/apps/advisor/go.mod @@ -8,14 +8,15 @@ require ( github.com/google/go-github/v70 v70.0.0 github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 github.com/grafana/grafana v0.0.0-00010101000000-000000000000 - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana-plugin-sdk-go v0.284.0 github.com/grafana/grafana/pkg/apimachinery v0.0.0 github.com/stretchr/testify v1.11.1 - k8s.io/apimachinery v0.34.2 - k8s.io/apiserver v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/apimachinery v0.34.3 + k8s.io/apiserver v0.34.3 + k8s.io/client-go v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) // transitive dependencies that need replaced @@ -43,6 +44,7 @@ replace github.com/grafana/grafana/apps/plugins => ../plugins replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604 require ( + cel.dev/expr v0.25.1 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect dario.cat/mergo v1.0.2 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -52,9 +54,11 @@ require ( 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/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/semver v1.5.0 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect + github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f // indirect github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect @@ -64,28 +68,29 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // 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-v2 v1.39.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.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.8 // 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.8 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 // indirect - github.com/aws/smithy-go v1.23.1 // indirect + github.com/aws/aws-sdk-go-v2 v1.40.0 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // 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/presigned-url v1.13.13 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // indirect + github.com/aws/smithy-go v1.23.2 // indirect github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bluele/gcache v0.0.2 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/cloudflare/circl v1.6.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-semver v0.3.1 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/diegoholiveira/jsonlogic/v3 v3.7.4 // indirect @@ -101,6 +106,7 @@ require ( github.com/evanphx/json-patch v5.9.11+incompatible // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/gchaincl/sqlhooks v1.3.0 // indirect github.com/getkin/kin-openapi v0.133.0 // indirect @@ -113,22 +119,24 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.24.0 // indirect github.com/go-openapi/errors v0.22.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/loads v0.23.1 // indirect github.com/go-openapi/runtime v0.28.0 // indirect github.com/go-openapi/spec v0.22.0 // indirect github.com/go-openapi/strfmt v0.24.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/conv v0.25.1 // indirect - github.com/go-openapi/swag/fileutils v0.25.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect - github.com/go-openapi/swag/jsonutils v0.25.1 // indirect - github.com/go-openapi/swag/loading v0.25.1 // indirect - github.com/go-openapi/swag/mangling v0.25.1 // indirect - github.com/go-openapi/swag/stringutils v0.25.1 // indirect - github.com/go-openapi/swag/typeutils v0.25.1 // indirect - github.com/go-openapi/swag/yamlutils v0.25.1 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-openapi/validate v0.25.0 // indirect github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/go-stack/stack v1.8.1 // indirect @@ -144,24 +152,27 @@ require ( github.com/golang-migrate/migrate/v4 v4.7.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect + github.com/google/cel-go v0.26.1 // indirect github.com/google/flatbuffers v25.2.10+incompatible // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/google/wire v0.7.0 // indirect - github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba // indirect + github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f // indirect github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect - github.com/grafana/grafana-aws-sdk v1.3.0 // indirect + github.com/grafana/grafana-aws-sdk v1.4.2 // 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/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/pyroscope-go/godeltaprof v0.1.9 // indirect - github.com/grafana/sqlds/v4 v4.2.7 // indirect + github.com/grafana/sqlds/v5 v5.0.3 // 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-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect @@ -176,6 +187,7 @@ require ( github.com/hashicorp/memberlist v0.5.2 // indirect github.com/hashicorp/yamux v0.1.2 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jaegertracing/jaeger-idl v0.5.0 // indirect github.com/jessevdk/go-flags v1.6.1 // indirect github.com/jmespath-community/go-jmespath v1.1.1 // indirect @@ -190,7 +202,7 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/lestrrat-go/strftime v1.0.4 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -233,10 +245,10 @@ require ( github.com/prometheus/alertmanager v0.28.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect + github.com/prometheus/common v0.67.4 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.14.0 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/redis/go-redis/v9 v9.14.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect @@ -248,73 +260,83 @@ require ( github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cast v1.10.0 // indirect + github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect + github.com/stoewer/go-strcase v1.3.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tetratelabs/wazero v1.8.2 // indirect github.com/thomaspoignant/go-feature-flag v1.42.0 // indirect github.com/tjhop/slog-gokit v0.1.5 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect + go.etcd.io/etcd/api/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/v3 v3.6.6 // indirect go.mongodb.org/mongo-driver v1.17.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.6.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect golang.org/x/tools/godoc v0.1.0-deprecated // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/mail.v2 v2.3.1 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/src-d/go-errors.v1 v1.0.0 // indirect gopkg.in/telebot.v3 v3.3.8 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect - k8s.io/component-base v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/component-base v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect + k8s.io/kms v0.34.3 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect modernc.org/libc v1.66.10 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect modernc.org/sqlite v1.40.1 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/advisor/go.sum b/apps/advisor/go.sum index 4695785bbd1..c306b9fa889 100644 --- a/apps/advisor/go.sum +++ b/apps/advisor/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= @@ -115,6 +115,8 @@ 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/IBM/pgxpoolprometheus v1.1.2 h1:sHJwxoL5Lw4R79Zt+H4Uj1zZ4iqXJLdk7XDE7TPs97U= 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/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -171,44 +173,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.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.39.1 h1:fWZhGAwVRK/fAN2tmt7ilH4PPAE11rDj7HytrmbZ2FE= -github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc= +github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= 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/config v1.31.10 h1:7LllDZAegXU3yk41mwM6KcPu0wmjKGQB1bg99bNdQm4= -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.14 h1:TxkI7QI+sFkTItN/6cJuMZEIVMFXeu2dI1ZffkXngKI= -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.8 h1:gLD09eaJUdiszm7vd1btiQUYE0Hj+0I2b8AS+75z9AY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.8/go.mod h1:4RW3oMPt1POR74qVOC4SbubxAwdP4pCT0nSw3jycOU4= +github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y= +github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c= +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.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= +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.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= 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/internal/configsources v1.4.8 h1:6bgAZgRyT4RoFWhxS+aoGMFyE0cD1bSzFnEEi4bFPGI= -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.8 h1:HhJYoES3zOz34yWEpGENqJvRVPqpmJyR3+AFg9ybhdY= -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.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -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/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I= +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/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY= +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/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= 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/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= -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/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o= +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/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/presigned-url v1.13.8 h1:M6JI2aGFEzYxsF6CXIuRBnkge9Wf9a2xU39rNeXgu10= -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/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= +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/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/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/sso v1.29.4 h1:FTdEN9dtWPB0EOURNtDPmwGp6GGvMqRJCAihkSl/1No= -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.0 h1:I7ghctfGXrscr7r1Ga/mDqSJKm7Fkpl5Mwq79Z+rZqU= -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.38.5 h1:+LVB0xBqEgjQoqr9bGZbRzvg212B0f17JdflleJRNR4= -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.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= -github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +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.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= +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.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= +github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= +github.com/aws/smithy-go v1.23.2/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/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= @@ -228,8 +230,8 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -280,8 +282,9 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= @@ -406,14 +409,16 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/analysis v0.24.0 h1:vE/VFFkICKyYuTWYnplQ+aVr45vlG6NcZKC7BdIXhsA= github.com/go-openapi/analysis v0.24.0/go.mod h1:GLyoJA+bvmGGaHgpfeDh8ldpGo69fAJg7eeMDMRCIrw= github.com/go-openapi/errors v0.22.3 h1:k6Hxa5Jg1TUyZnOwV2Lh81j8ayNw5VVYLvKrp4zFKFs= github.com/go-openapi/errors v0.22.3/go.mod h1:+WvbaBBULWCOna//9B9TbLNGSFOfF8lY9dw4hGiEiKQ= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/loads v0.23.1 h1:H8A0dX2KDHxDzc797h0+uiCZ5kwE2+VojaQVaTlXvS0= github.com/go-openapi/loads v0.23.1/go.mod h1:hZSXkyACCWzWPQqizAv/Ye0yhi2zzHwMmoXQ6YQml44= github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= @@ -422,28 +427,36 @@ github.com/go-openapi/spec v0.22.0 h1:xT/EsX4frL3U09QviRIZXvkh80yibxQmtoEvyqug0T github.com/go-openapi/spec v0.22.0/go.mod h1:K0FhKxkez8YNS94XzF8YKEMULbFrRw4m15i2YUht4L0= github.com/go-openapi/strfmt v0.24.0 h1:dDsopqbI3wrrlIzeXRbqMihRNnjzGC+ez4NQaAAJLuc= github.com/go-openapi/strfmt v0.24.0/go.mod h1:Lnn1Bk9rZjXxU9VMADbEEOo7D7CDyKGLsSKekhFr7s4= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0= -github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs= -github.com/go-openapi/swag/fileutils v0.25.1 h1:rSRXapjQequt7kqalKXdcpIegIShhTPXx7yw0kek2uU= -github.com/go-openapi/swag/fileutils v0.25.1/go.mod h1:+NXtt5xNZZqmpIpjqcujqojGFek9/w55b3ecmOdtg8M= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= -github.com/go-openapi/swag/jsonutils v0.25.1 h1:AihLHaD0brrkJoMqEZOBNzTLnk81Kg9cWr+SPtxtgl8= -github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1 h1:DSQGcdB6G0N9c/KhtpYc71PzzGEIc/fZ1no35x4/XBY= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1/go.mod h1:kjmweouyPwRUEYMSrbAidoLMGeJ5p6zdHi9BgZiqmsg= -github.com/go-openapi/swag/loading v0.25.1 h1:6OruqzjWoJyanZOim58iG2vj934TysYVptyaoXS24kw= -github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc= -github.com/go-openapi/swag/mangling v0.25.1 h1:XzILnLzhZPZNtmxKaz/2xIGPQsBsvmCjrJOWGNz/ync= -github.com/go-openapi/swag/mangling v0.25.1/go.mod h1:CdiMQ6pnfAgyQGSOIYnZkXvqhnnwOn997uXZMAd/7mQ= -github.com/go-openapi/swag/stringutils v0.25.1 h1:Xasqgjvk30eUe8VKdmyzKtjkVjeiXx1Iz0zDfMNpPbw= -github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg= -github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3I3ysiFZqukA= -github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= -github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk= -github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-openapi/validate v0.25.0 h1:JD9eGX81hDTjoY3WOzh6WqxVBVl7xjsLnvDo1GL5WPU= github.com/go-openapi/validate v0.25.0/go.mod h1:SUY7vKrN5FiwK6LyvSwKjDfLNirSfWwHNgxd2l29Mmw= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -534,8 +547,8 @@ github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ= github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -606,8 +619,10 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba h1:psKWNETD5nGxmFAlqnWsXoRyUwSa2GHNEMSEDKGKfQ4= -github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU= +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/grafana/alerting v0.0.0-20251231150637-b7821017d69f h1:Br4SaUL3dnVopKKNhDavCLgehw60jdtl/sIxdfzmVts= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f/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/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg= github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGrHj3GdFbvsMzUT7eusgii9PKf9L1ZaXDDbY= @@ -618,12 +633,12 @@ github.com/grafana/dataplane/sdata v0.0.9 h1:AGL1LZnCUG4MnQtnWpBPbQ8ZpptaZs14w6k github.com/grafana/dataplane/sdata v0.0.9/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= 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/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= -github.com/grafana/grafana-aws-sdk v1.3.0 h1:/bfJzP93rCel1GbWoRSq0oUo424MZXt8jAp2BK9w8tM= -github.com/grafana/grafana-aws-sdk v1.3.0/go.mod h1:VGycF0JkCGKND2O5je1ucOqPJ0ZNhZYzV3c2bNBAaGk= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= +github.com/grafana/grafana-aws-sdk v1.4.2 h1:GrUEoLbs46r8rG/GZL4L2b63Bo+rkIYKdtCT7kT5KkM= +github.com/grafana/grafana-aws-sdk v1.4.2/go.mod h1:1qnZdYs6gQzxxF0dDodaE7Rn9fiMzuhwvtaAZ7ySnhY= 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-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad0a5JpEL4mH9ry7Ws= @@ -640,8 +655,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/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/sqlds/v4 v4.2.7 h1:sFQhsS7DBakNMdxa++yOfJ9BVvkZwFJ0B95o57K0/XA= -github.com/grafana/sqlds/v4 v4.2.7/go.mod h1:BQRjUG8rOqrBI4NAaeoWrIMuoNgfi8bdhCJ+5cgEfLU= +github.com/grafana/sqlds/v5 v5.0.3 h1:+yUMUxfa0WANQsmS9xtTFSRX1Q55Iv1B9EjlrW4VlBU= +github.com/grafana/sqlds/v5 v5.0.3/go.mod h1:GKeTTiC+GeR1X0z3f0Iee+hZnNgN62uQpj5XVMx5Uew= 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/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o= @@ -749,6 +764,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= @@ -811,8 +828,8 @@ github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/madflojo/testcerts v1.4.0 h1:I09gN0C1ly9IgeVNcAqKk8RAKIJTe3QnFrrPBDyvzN4= github.com/madflojo/testcerts v1.4.0/go.mod h1:MW8sh39gLnkKh4K0Nc55AyHEDl9l/FBLDUsQhpmkuo0= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 h1:hQWBtNqRYrI7CWIaUSXXtNKR90KzcUA5uiuxFVWw7sU= github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM= @@ -979,6 +996,7 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg github.com/pressly/goose/v3 v3.26.0 h1:KJakav68jdH0WDvoAcj8+n61WqOIaPGgH0bJWS6jpmM= github.com/pressly/goose/v3 v3.26.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= @@ -996,6 +1014,7 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= @@ -1003,20 +1022,21 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg= github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/prometheus/prometheus v0.303.1 h1:He/2jRE6sB23Ew38AIoR1WRR3fCMgPlJA2E0obD2WSY= github.com/prometheus/prometheus v0.303.1/go.mod h1:WEq2ogBPZoLjj9x5K67VEk7ECR0nRD9XCjaOt1lsYck= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= @@ -1036,6 +1056,7 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= @@ -1058,6 +1079,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1067,10 +1090,11 @@ github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8 github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= @@ -1096,6 +1120,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= @@ -1112,6 +1137,8 @@ github.com/thomaspoignant/go-feature-flag v1.42.0/go.mod h1:y0QiWH7chHWhGATb/+Xq github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tjhop/slog-gokit v0.1.5 h1:ayloIUi5EK2QYB8eY4DOPO95/mRtMW42lUkp3quJohc= github.com/tjhop/slog-gokit v0.1.5/go.mod h1:yA48zAHvV+Sg4z4VRyeFyFUNNXd3JY5Zg84u3USICq0= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= @@ -1122,13 +1149,15 @@ github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZ github.com/wk8/go-ordered-map v1.0.0 h1:BV7z+2PaK8LTSd/mWgY12HyMAo5CEgkHqbkVq2thqr8= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk= +github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1139,16 +1168,24 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= +go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= +go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= +go.etcd.io/etcd/api/v3 v3.6.6 h1:mcaMp3+7JawWv69p6QShYWS8cIWUOl32bFLb6qf8pOQ= +go.etcd.io/etcd/api/v3 v3.6.6/go.mod h1:f/om26iXl2wSkcTA1zGQv8reJRSLVdoEBsi4JdfMrx4= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= +go.etcd.io/etcd/client/pkg/v3 v3.6.6 h1:uoqgzSOv2H9KlIF5O1Lsd8sW+eMLuV6wzE3q5GJGQNs= +go.etcd.io/etcd/client/pkg/v3 v3.6.6/go.mod h1:YngfUVmvsvOJ2rRgStIyHsKtOt9SZI2aBJrZiWJhCbI= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/client/v3 v3.6.6 h1:G5z1wMf5B9SNexoxOHUGBaULurOZPIgGPsW6CN492ec= +go.etcd.io/etcd/client/v3 v3.6.6/go.mod h1:36Qv6baQ07znPR3+n7t+Rk5VHEzVYPvFfGmfF4wBHV8= +go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA= +go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE= +go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU= +go.etcd.io/etcd/server/v3 v3.6.4/go.mod h1:aYCL/h43yiONOv0QIR82kH/2xZ7m+IWYjzRmyQfnCAg= +go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ= +go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.17.4 h1:jUorfmVzljjr0FLzYQsGP8cgN/qzzxlY9Vh0C9KFXVw= go.mongodb.org/mongo-driver v1.17.4/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= @@ -1168,19 +1205,19 @@ go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 h1:2pn7OzMewmYRiNtv1doZnLo3gONcnMHlFnmOR8Vgt+8= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0/go.mod h1:rjbQTDEPQymPE0YnRQp9/NuPwwtL0sesz/fnqRW/v84= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 h1:nXGeLvT1QtCAhkASkP/ksjkTKZALIaQBIW+JSIw1KIc= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0/go.mod h1:oMvOXk78ZR3KEuPMBgp/ThAMDy9ku/eyUVztr+3G6Wo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 h1:oPW/SRFyHgIgxrvNhSBzqvZER2N5kRlci3/rGTOuyWo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0/go.mod h1:B9Oka5QVD0bnmZNO6gBbBta6nohD/1Z+f9waH2oXyBs= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= @@ -1191,12 +1228,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= @@ -1208,18 +1245,18 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7i go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= @@ -1255,8 +1292,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1267,8 +1304,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1294,13 +1331,14 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1349,8 +1387,8 @@ golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1373,8 +1411,8 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1387,8 +1425,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1477,14 +1515,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1494,8 +1532,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1559,8 +1597,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1707,11 +1745,12 @@ google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1759,8 +1798,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -1770,8 +1809,8 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -1808,26 +1847,26 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= -k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ= -k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/component-base v0.34.3 h1:zsEgw6ELqK0XncCQomgO9DpUIzlrYuZYA0Cgo+JWpVk= +k8s.io/component-base v0.34.3/go.mod h1:5iIlD8wPfWE/xSHTRfbjuvUul2WZbI2nOUK65XL0E/c= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.34.2 h1:91rj4MDZLyIT9KxG8J5/CcMH666Z88CF/xJQeuPfJc8= -k8s.io/kms v0.34.2/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kms v0.34.3 h1:QzBOD0sk1bGQVMcZQAHGjtbP1iKZJUyhC6D0I+BTxIE= +k8s.io/kms v0.34.3/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4= modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A= @@ -1857,10 +1896,10 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/advisor/pkg/app/app.go b/apps/advisor/pkg/app/app.go index 9c1dd3c0f98..114b1fbabce 100644 --- a/apps/advisor/pkg/app/app.go +++ b/apps/advisor/pkg/app/app.go @@ -8,18 +8,24 @@ import ( "github.com/grafana/grafana-app-sdk/app" "github.com/grafana/grafana-app-sdk/k8s" + appsdkapiserver "github.com/grafana/grafana-app-sdk/k8s/apiserver" "github.com/grafana/grafana-app-sdk/logging" "github.com/grafana/grafana-app-sdk/operator" "github.com/grafana/grafana-app-sdk/resource" "github.com/grafana/grafana-app-sdk/simple" + advisorapi "github.com/grafana/grafana/apps/advisor/pkg/apis" advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" "github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry" "github.com/grafana/grafana/apps/advisor/pkg/app/checks" "github.com/grafana/grafana/apps/advisor/pkg/app/checkscheduler" "github.com/grafana/grafana/apps/advisor/pkg/app/checktyperegisterer" "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/services/org" + "github.com/grafana/grafana/pkg/setting" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/authorization/authorizer" + "k8s.io/client-go/rest" ) func New(cfg app.Config) (app.App, error) { @@ -188,3 +194,45 @@ func GetKinds() map[schema.GroupVersion][]resource.Kind { }, } } + +func ProvideAppInstaller( + authorizer authorizer.Authorizer, + checkRegistry checkregistry.CheckService, + cfg *setting.Cfg, + orgService org.Service, +) (*AdvisorAppInstaller, error) { + provider := simple.NewAppProvider(advisorapi.LocalManifest(), nil, New) + pluginConfig := cfg.PluginSettings["grafana-advisor-app"] + specificConfig := checkregistry.AdvisorAppConfig{ + CheckRegistry: checkRegistry, + PluginConfig: pluginConfig, + StackID: cfg.StackID, + OrgService: orgService, + } + appCfg := app.Config{ + KubeConfig: rest.Config{}, + ManifestData: *advisorapi.LocalManifest().ManifestData, + SpecificConfig: specificConfig, + } + + defaultInstaller, err := appsdkapiserver.NewDefaultAppInstaller(provider, appCfg, advisorapi.NewGoTypeAssociator()) + if err != nil { + return nil, err + } + + installer := &AdvisorAppInstaller{ + AppInstaller: defaultInstaller, + authorizer: authorizer, + } + + return installer, nil +} + +type AdvisorAppInstaller struct { + appsdkapiserver.AppInstaller + authorizer authorizer.Authorizer +} + +func (a *AdvisorAppInstaller) GetAuthorizer() authorizer.Authorizer { + return a.authorizer +} diff --git a/apps/advisor/pkg/app/authorizer.go b/apps/advisor/pkg/app/authorizer.go deleted file mode 100644 index 576773330e3..00000000000 --- a/apps/advisor/pkg/app/authorizer.go +++ /dev/null @@ -1,47 +0,0 @@ -package app - -import ( - "context" - - claims "github.com/grafana/authlib/types" - "github.com/grafana/grafana/pkg/apimachinery/identity" - "k8s.io/apiserver/pkg/authorization/authorizer" -) - -func GetAuthorizer() authorizer.Authorizer { - return authorizer.AuthorizerFunc(func( - ctx context.Context, attr authorizer.Attributes, - ) (authorized authorizer.Decision, reason string, err error) { - if !attr.IsResourceRequest() { - return authorizer.DecisionNoOpinion, "", nil - } - - // Check for service identity - if identity.IsServiceIdentity(ctx) { - return authorizer.DecisionAllow, "", nil - } - - // Check for access policy identity - info, ok := claims.AuthInfoFrom(ctx) - if ok && claims.IsIdentityType(info.GetIdentityType(), claims.TypeAccessPolicy) { - // For access policy identities, we need to use ResourceAuthorizer - // This requires an AccessClient, which should be provided by the API server - // For now, we'll use the default ResourceAuthorizer from the API server - // This will be set up by the API server's authorization chain - return authorizer.DecisionNoOpinion, "", nil - } - - // For regular Grafana users, check if they are admin - u, err := identity.GetRequester(ctx) - if err != nil { - return authorizer.DecisionDeny, "valid user is required", err - } - - // check if is admin - if u.HasRole(identity.RoleAdmin) { - return authorizer.DecisionAllow, "", nil - } - - return authorizer.DecisionDeny, "forbidden", nil - }) -} diff --git a/apps/advisor/pkg/app/authorizer_test.go b/apps/advisor/pkg/app/authorizer_test.go deleted file mode 100644 index de8c0fad2db..00000000000 --- a/apps/advisor/pkg/app/authorizer_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package app - -import ( - "context" - "testing" - - claims "github.com/grafana/authlib/types" - "github.com/grafana/grafana/pkg/apimachinery/identity" - "github.com/stretchr/testify/assert" - "k8s.io/apiserver/pkg/authorization/authorizer" -) - -func TestGetAuthorizer(t *testing.T) { - tests := []struct { - name string - ctx context.Context - attr authorizer.Attributes - expectedDecision authorizer.Decision - expectedReason string - expectedErr error - }{ - { - name: "non-resource request", - ctx: context.TODO(), - attr: &mockAttributes{resourceRequest: false}, - expectedDecision: authorizer.DecisionNoOpinion, - expectedReason: "", - expectedErr: nil, - }, - { - name: "user is admin", - ctx: identity.WithRequester(context.TODO(), &mockUser{isGrafanaAdmin: true}), - attr: &mockAttributes{resourceRequest: true}, - expectedDecision: authorizer.DecisionAllow, - expectedReason: "", - expectedErr: nil, - }, - { - name: "user is not admin", - ctx: identity.WithRequester(context.TODO(), &mockUser{isGrafanaAdmin: false}), - attr: &mockAttributes{resourceRequest: true}, - expectedDecision: authorizer.DecisionDeny, - expectedReason: "forbidden", - expectedErr: nil, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - auth := GetAuthorizer() - decision, reason, err := auth.Authorize(tt.ctx, tt.attr) - assert.Equal(t, tt.expectedDecision, decision) - assert.Equal(t, tt.expectedReason, reason) - assert.Equal(t, tt.expectedErr, err) - }) - } -} - -type mockAttributes struct { - authorizer.Attributes - resourceRequest bool -} - -func (m *mockAttributes) IsResourceRequest() bool { - return m.resourceRequest -} - -// Implement other methods of authorizer.Attributes as needed - -type mockUser struct { - identity.Requester - isGrafanaAdmin bool -} - -func (m *mockUser) GetIsGrafanaAdmin() bool { - return m.isGrafanaAdmin -} - -func (m *mockUser) HasRole(role identity.RoleType) bool { - return role == identity.RoleAdmin && m.isGrafanaAdmin -} - -func (m *mockUser) GetUID() string { - return "test-uid" -} - -func (m *mockUser) GetIdentityType() claims.IdentityType { - return claims.TypeUser -} - -// Implement other methods of identity.Requester as needed diff --git a/apps/alerting/alertenrichment/go.mod b/apps/alerting/alertenrichment/go.mod index bb020e52bff..792ad18eeac 100644 --- a/apps/alerting/alertenrichment/go.mod +++ b/apps/alerting/alertenrichment/go.mod @@ -3,38 +3,48 @@ module github.com/grafana/grafana/apps/alerting/alertenrichment go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 + github.com/grafana/grafana-app-sdk v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250901080157-a0280d701b28 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/josharian/intern v1.0.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/x448/float16 v0.8.4 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect ) diff --git a/apps/alerting/alertenrichment/go.sum b/apps/alerting/alertenrichment/go.sum index ef36568611c..9b83516bea0 100644 --- a/apps/alerting/alertenrichment/go.sum +++ b/apps/alerting/alertenrichment/go.sum @@ -1,3 +1,4 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -8,46 +9,73 @@ github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sa github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +github.com/grafana/grafana-app-sdk v0.48.7/go.mod h1:DWsaaH39ZMHwSOSoUBaeW8paMrRaYsjRYlLwCJYd78k= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250901080157-a0280d701b28 h1:PgMfX4OPENz/iXmtDDIW9+poZY4UD0hhmXm7flVclDo= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250901080157-a0280d701b28/go.mod h1:av5N0Naq+8VV9MLF7zAkihy/mVq5UbS2EvRSJukDHlY= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -73,8 +101,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -83,8 +111,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -93,8 +121,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -102,16 +130,16 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/alerting/historian/go.mod b/apps/alerting/historian/go.mod index 21ad42c90af..a79829d45c2 100644 --- a/apps/alerting/historian/go.mod +++ b/apps/alerting/historian/go.mod @@ -4,17 +4,17 @@ go 1.25.5 require ( github.com/go-kit/log v0.2.1 - github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba + github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/prometheus/client_golang v1.23.2 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/otel v1.38.0 - go.opentelemetry.io/otel/trace v1.38.0 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + go.opentelemetry.io/otel v1.39.0 + go.opentelemetry.io/otel/trace v1.39.0 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( @@ -28,11 +28,11 @@ require ( github.com/aws/aws-sdk-go v1.55.7 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/evanphx/json-patch v5.9.11+incompatible // indirect @@ -42,11 +42,21 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/errors v0.22.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/strfmt v0.24.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect @@ -57,7 +67,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -80,7 +90,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mdlayher/socket v0.4.1 // indirect github.com/mdlayher/vsock v1.2.1 // indirect @@ -104,10 +114,10 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/alertmanager v0.28.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect + github.com/prometheus/common v0.67.4 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.14.0 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/shopspring/decimal v1.4.0 // indirect @@ -117,7 +127,7 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.mongodb.org/mongo-driver v1.17.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect @@ -130,49 +140,49 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.37.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.12.2 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect golang.org/x/tools/godoc v0.1.0-deprecated // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/mail.v2 v2.3.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/alerting/historian/go.sum b/apps/alerting/historian/go.sum index b4d2d1dc2e2..d45d418dfb8 100644 --- a/apps/alerting/historian/go.sum +++ b/apps/alerting/historian/go.sum @@ -63,8 +63,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= @@ -80,8 +80,8 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -123,16 +123,42 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/errors v0.22.3 h1:k6Hxa5Jg1TUyZnOwV2Lh81j8ayNw5VVYLvKrp4zFKFs= github.com/go-openapi/errors v0.22.3/go.mod h1:+WvbaBBULWCOna//9B9TbLNGSFOfF8lY9dw4hGiEiKQ= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/strfmt v0.24.0 h1:dDsopqbI3wrrlIzeXRbqMihRNnjzGC+ez4NQaAAJLuc= github.com/go-openapi/strfmt v0.24.0/go.mod h1:Lnn1Bk9rZjXxU9VMADbEEOo7D7CDyKGLsSKekhFr7s4= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= @@ -140,7 +166,6 @@ github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= @@ -187,8 +212,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -216,16 +241,16 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= 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/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba h1:psKWNETD5nGxmFAlqnWsXoRyUwSa2GHNEMSEDKGKfQ4= -github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f h1:Br4SaUL3dnVopKKNhDavCLgehw60jdtl/sIxdfzmVts= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU= 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/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/loki/pkg/push v0.0.0-20250823105456-332df2b20000 h1:/5LKSYgLmAhwA4m6iGUD4w1YkydEWWjazn9qxCFT8W0= github.com/grafana/loki/pkg/push v0.0.0-20250823105456-332df2b20000/go.mod h1:/ZklAgE1i4f3Z8uriXwESmCr1VLF8lBGaJspuaGuf78= github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= @@ -301,8 +326,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -376,8 +401,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg= @@ -387,8 +412,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -431,8 +456,8 @@ github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVK github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -457,8 +482,8 @@ go.opentelemetry.io/contrib/propagators/jaeger v1.38.0/go.mod h1:oMvOXk78ZR3KEuP go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 h1:oPW/SRFyHgIgxrvNhSBzqvZER2N5kRlci3/rGTOuyWo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0/go.mod h1:B9Oka5QVD0bnmZNO6gBbBta6nohD/1Z+f9waH2oXyBs= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= @@ -469,12 +494,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= @@ -486,20 +511,20 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7i go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -516,8 +541,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -552,8 +577,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -585,16 +610,16 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -605,8 +630,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -644,19 +669,19 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -706,8 +731,8 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -774,10 +799,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -804,8 +829,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -816,8 +841,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= @@ -840,26 +865,26 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/alerting/historian/pkg/app/notification/lokireader.go b/apps/alerting/historian/pkg/app/notification/lokireader.go index c26519e59b4..636ae083d91 100644 --- a/apps/alerting/historian/pkg/app/notification/lokireader.go +++ b/apps/alerting/historian/pkg/app/notification/lokireader.go @@ -31,6 +31,10 @@ const ( maxLimit = 1000 Namespace = "grafana" 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 ( @@ -111,13 +115,13 @@ func buildQuery(query Query) (string, error) { fmt.Sprintf(`%s=%q`, historian.LabelFrom, historian.LabelFromValue), } - if query.RuleUID != nil { - selectors = append(selectors, - fmt.Sprintf(`%s=%q`, historian.LabelRuleUID, *query.RuleUID)) - } - logql := fmt.Sprintf(`{%s} | json`, strings.Join(selectors, `,`)) + // Add ruleUID filter as JSON line filter if specified. + if query.RuleUID != nil && *query.RuleUID != "" { + logql += fmt.Sprintf(` | %s = %q`, lokiAlertRuleUIDField, *query.RuleUID) + } + // Add receiver filter if specified. if query.Receiver != nil && *query.Receiver != "" { logql += fmt.Sprintf(` | receiver = %q`, *query.Receiver) @@ -211,16 +215,13 @@ func parseLokiEntry(s lokiclient.Sample) (Entry, error) { groupLabels = make(map[string]string) } - alerts := make([]EntryAlert, len(lokiEntry.Alerts)) - for i, a := range lokiEntry.Alerts { - alerts[i] = EntryAlert{ - Status: a.Status, - Labels: a.Labels, - Annotations: a.Annotations, - StartsAt: a.StartsAt, - EndsAt: a.EndsAt, - } - } + alerts := []EntryAlert{{ + Status: lokiEntry.Alert.Status, + Labels: lokiEntry.Alert.Labels, + Annotations: lokiEntry.Alert.Annotations, + StartsAt: lokiEntry.Alert.StartsAt, + EndsAt: lokiEntry.Alert.EndsAt, + }} return Entry{ Timestamp: s.T, diff --git a/apps/alerting/historian/pkg/app/notification/lokireader_test.go b/apps/alerting/historian/pkg/app/notification/lokireader_test.go index 708c9d10df1..c9c35cb1e62 100644 --- a/apps/alerting/historian/pkg/app/notification/lokireader_test.go +++ b/apps/alerting/historian/pkg/app/notification/lokireader_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/grafana/alerting/models" "github.com/grafana/alerting/notify/historian" "github.com/grafana/alerting/notify/historian/lokiclient" "github.com/grafana/grafana-app-sdk/logging" @@ -133,9 +134,8 @@ func TestBuildQuery(t *testing.T) { query: Query{ RuleUID: stringPtr("test-rule-uid"), }, - expected: fmt.Sprintf(`{%s=%q,%s=%q} | json`, - historian.LabelFrom, historian.LabelFromValue, - historian.LabelRuleUID, "test-rule-uid"), + expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid"`, + historian.LabelFrom, historian.LabelFromValue), }, { name: "query with receiver filter", @@ -143,9 +143,8 @@ func TestBuildQuery(t *testing.T) { RuleUID: stringPtr("test-rule-uid"), Receiver: stringPtr("email-receiver"), }, - expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | receiver = "email-receiver"`, - historian.LabelFrom, historian.LabelFromValue, - historian.LabelRuleUID, "test-rule-uid"), + expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | receiver = "email-receiver"`, + historian.LabelFrom, historian.LabelFromValue), }, { name: "query with status filter", @@ -153,9 +152,8 @@ func TestBuildQuery(t *testing.T) { RuleUID: stringPtr("test-rule-uid"), Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusFiring), }, - expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | status = "firing"`, - historian.LabelFrom, historian.LabelFromValue, - historian.LabelRuleUID, "test-rule-uid"), + expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | status = "firing"`, + historian.LabelFrom, historian.LabelFromValue), }, { name: "query with success outcome filter", @@ -163,9 +161,8 @@ func TestBuildQuery(t *testing.T) { RuleUID: stringPtr("test-rule-uid"), Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess), }, - expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | error = ""`, - historian.LabelFrom, historian.LabelFromValue, - historian.LabelRuleUID, "test-rule-uid"), + expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | error = ""`, + historian.LabelFrom, historian.LabelFromValue), }, { name: "query with error outcome filter", @@ -173,9 +170,8 @@ func TestBuildQuery(t *testing.T) { RuleUID: stringPtr("test-rule-uid"), Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeError), }, - expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | error != ""`, - historian.LabelFrom, historian.LabelFromValue, - historian.LabelRuleUID, "test-rule-uid"), + expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | error != ""`, + historian.LabelFrom, historian.LabelFromValue), }, { name: "query with many filters", @@ -185,9 +181,8 @@ func TestBuildQuery(t *testing.T) { Status: createStatusPtr(v0alpha1.CreateNotificationqueryRequestNotificationStatusResolved), Outcome: outcomePtr(v0alpha1.CreateNotificationqueryRequestNotificationOutcomeSuccess), }, - expected: fmt.Sprintf(`{%s=%q,%s=%q} | json | receiver = "email-receiver" | status = "resolved" | error = ""`, - historian.LabelFrom, historian.LabelFromValue, - historian.LabelRuleUID, "test-rule-uid"), + expected: fmt.Sprintf(`{%s=%q} | json | alert_labels___alert_rule_uid__ = "test-rule-uid" | receiver = "email-receiver" | status = "resolved" | error = ""`, + historian.LabelFrom, historian.LabelFromValue), }, { name: "query with group label matcher", @@ -277,19 +272,19 @@ func TestParseLokiEntry(t *testing.T) { GroupLabels: map[string]string{ "alertname": "test-alert", }, - Alerts: []historian.NotificationHistoryLokiEntryAlert{ - { - Status: "firing", - Labels: map[string]string{ - "severity": "critical", - }, - Annotations: map[string]string{ - "summary": "Test alert", - }, - StartsAt: now, - EndsAt: now.Add(1 * time.Hour), + Alert: historian.NotificationHistoryLokiEntryAlert{ + Status: "firing", + Labels: map[string]string{ + "severity": "critical", }, + Annotations: map[string]string{ + "summary": "Test alert", + }, + StartsAt: now, + EndsAt: now.Add(1 * time.Hour), }, + AlertIndex: 0, + AlertCount: 1, Retry: false, Duration: 100, PipelineTime: now, @@ -335,7 +330,9 @@ func TestParseLokiEntry(t *testing.T) { Error: "notification failed", GroupKey: "key:thing", GroupLabels: map[string]string{}, - Alerts: []historian.NotificationHistoryLokiEntryAlert{}, + Alert: historian.NotificationHistoryLokiEntryAlert{}, + AlertIndex: 0, + AlertCount: 1, PipelineTime: now, }), }, @@ -347,7 +344,7 @@ func TestParseLokiEntry(t *testing.T) { Outcome: OutcomeError, GroupKey: "key:thing", GroupLabels: map[string]string{}, - Alerts: []EntryAlert{}, + Alerts: []EntryAlert{{}}, Error: stringPtr("notification failed"), PipelineTime: now, }, @@ -365,7 +362,7 @@ func TestParseLokiEntry(t *testing.T) { Status: Status("firing"), Outcome: OutcomeSuccess, GroupLabels: map[string]string{}, - Alerts: []EntryAlert{}, + Alerts: []EntryAlert{{}}, PipelineTime: now, }, }, @@ -448,7 +445,9 @@ func TestLokiReader_RunQuery(t *testing.T) { Receiver: "receiver-1", Status: "firing", GroupLabels: map[string]string{}, - Alerts: []historian.NotificationHistoryLokiEntryAlert{}, + Alert: historian.NotificationHistoryLokiEntryAlert{}, + AlertIndex: 0, + AlertCount: 1, PipelineTime: now, }), }, @@ -459,7 +458,9 @@ func TestLokiReader_RunQuery(t *testing.T) { Receiver: "receiver-3", Status: "firing", GroupLabels: map[string]string{}, - Alerts: []historian.NotificationHistoryLokiEntryAlert{}, + Alert: historian.NotificationHistoryLokiEntryAlert{}, + AlertIndex: 0, + AlertCount: 1, PipelineTime: now, }), }, @@ -474,7 +475,9 @@ func TestLokiReader_RunQuery(t *testing.T) { Receiver: "receiver-2", Status: "firing", GroupLabels: map[string]string{}, - Alerts: []historian.NotificationHistoryLokiEntryAlert{}, + Alert: historian.NotificationHistoryLokiEntryAlert{}, + AlertIndex: 0, + AlertCount: 1, PipelineTime: now, }), }, @@ -546,19 +549,19 @@ func createMockLokiResponse(timestamp time.Time) lokiclient.QueryRes { GroupLabels: map[string]string{ "alertname": "test-alert", }, - Alerts: []historian.NotificationHistoryLokiEntryAlert{ - { - Status: "firing", - Labels: map[string]string{ - "severity": "critical", - }, - Annotations: map[string]string{ - "summary": "Test alert", - }, - StartsAt: timestamp, - EndsAt: timestamp.Add(1 * time.Hour), + Alert: historian.NotificationHistoryLokiEntryAlert{ + Status: "firing", + Labels: map[string]string{ + "severity": "critical", }, + Annotations: map[string]string{ + "summary": "Test alert", + }, + StartsAt: timestamp, + EndsAt: timestamp.Add(1 * time.Hour), }, + AlertIndex: 0, + AlertCount: 1, Retry: false, Duration: 100, PipelineTime: timestamp, @@ -587,10 +590,19 @@ func createLokiEntryJSONWithNilLabels(t *testing.T, timestamp time.Time) string "status": "firing", "error": "", "groupLabels": null, - "alerts": [], + "alert": {}, + "alertIndex": 0, + "alertCount": 1, "retry": false, "duration": 0, "pipelineTime": "%s" }`, timestamp.Format(time.RFC3339Nano)) 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) +} diff --git a/apps/alerting/notifications/go.mod b/apps/alerting/notifications/go.mod index f72c4c9775b..b958cb377aa 100644 --- a/apps/alerting/notifications/go.mod +++ b/apps/alerting/notifications/go.mod @@ -3,21 +3,21 @@ module github.com/grafana/grafana/apps/alerting/notifications go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 - k8s.io/apimachinery v0.34.2 - k8s.io/apiserver v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 + k8s.io/apimachinery v0.34.3 + k8s.io/apiserver v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/evanphx/json-patch v5.9.11+incompatible // indirect @@ -26,14 +26,24 @@ require ( github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -44,7 +54,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -54,57 +64,56 @@ require ( github.com/onsi/ginkgo/v2 v2.22.2 // indirect github.com/onsi/gomega v1.36.2 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.etcd.io/etcd/api/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/v3 v3.6.4 // indirect + go.etcd.io/etcd/api/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/v3 v3.6.6 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect - k8s.io/component-base v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect + k8s.io/component-base v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/alerting/notifications/go.sum b/apps/alerting/notifications/go.sum index 57b099ab2f1..ea54639af1d 100644 --- a/apps/alerting/notifications/go.sum +++ b/apps/alerting/notifications/go.sum @@ -4,8 +4,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -13,8 +13,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -36,19 +36,44 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= @@ -60,8 +85,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -71,10 +96,10 @@ 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/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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= 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/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= @@ -104,8 +129,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -127,8 +152,6 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -140,11 +163,11 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -165,8 +188,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7 github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk= @@ -175,12 +198,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/api/v3 v3.6.6 h1:mcaMp3+7JawWv69p6QShYWS8cIWUOl32bFLb6qf8pOQ= +go.etcd.io/etcd/api/v3 v3.6.6/go.mod h1:f/om26iXl2wSkcTA1zGQv8reJRSLVdoEBsi4JdfMrx4= +go.etcd.io/etcd/client/pkg/v3 v3.6.6 h1:uoqgzSOv2H9KlIF5O1Lsd8sW+eMLuV6wzE3q5GJGQNs= +go.etcd.io/etcd/client/pkg/v3 v3.6.6/go.mod h1:YngfUVmvsvOJ2rRgStIyHsKtOt9SZI2aBJrZiWJhCbI= +go.etcd.io/etcd/client/v3 v3.6.6 h1:G5z1wMf5B9SNexoxOHUGBaULurOZPIgGPsW6CN492ec= +go.etcd.io/etcd/client/v3 v3.6.6/go.mod h1:36Qv6baQ07znPR3+n7t+Rk5VHEzVYPvFfGmfF4wBHV8= go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA= go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE= go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU= @@ -189,26 +212,26 @@ go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ= go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -224,8 +247,8 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -236,30 +259,30 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -267,8 +290,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -279,20 +302,20 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= @@ -300,28 +323,28 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= -k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ= -k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/component-base v0.34.3 h1:zsEgw6ELqK0XncCQomgO9DpUIzlrYuZYA0Cgo+JWpVk= +k8s.io/component-base v0.34.3/go.mod h1:5iIlD8wPfWE/xSHTRfbjuvUul2WZbI2nOUK65XL0E/c= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/alerting/notifications/kinds/v0alpha1/template_spec.cue b/apps/alerting/notifications/kinds/v0alpha1/template_spec.cue index 4c3157f39a4..297d3331eeb 100644 --- a/apps/alerting/notifications/kinds/v0alpha1/template_spec.cue +++ b/apps/alerting/notifications/kinds/v0alpha1/template_spec.cue @@ -1,6 +1,9 @@ package v0alpha1 +TemplateKind: *"grafana" | "mimir" + TemplateGroupSpec: { title: string content: string + kind: TemplateKind } diff --git a/apps/alerting/notifications/pkg/apis/alertingnotifications/v0alpha1/templategroup_spec_gen.go b/apps/alerting/notifications/pkg/apis/alertingnotifications/v0alpha1/templategroup_spec_gen.go index ecba2959665..2f4fee39b9e 100644 --- a/apps/alerting/notifications/pkg/apis/alertingnotifications/v0alpha1/templategroup_spec_gen.go +++ b/apps/alerting/notifications/pkg/apis/alertingnotifications/v0alpha1/templategroup_spec_gen.go @@ -2,13 +2,24 @@ package v0alpha1 +// +k8s:openapi-gen=true +type TemplateGroupTemplateKind string + +const ( + TemplateGroupTemplateKindGrafana TemplateGroupTemplateKind = "grafana" + TemplateGroupTemplateKindMimir TemplateGroupTemplateKind = "mimir" +) + // +k8s:openapi-gen=true type TemplateGroupSpec struct { - Title string `json:"title"` - Content string `json:"content"` + Title string `json:"title"` + Content string `json:"content"` + Kind TemplateGroupTemplateKind `json:"kind"` } // NewTemplateGroupSpec creates a new TemplateGroupSpec object. func NewTemplateGroupSpec() *TemplateGroupSpec { - return &TemplateGroupSpec{} + return &TemplateGroupSpec{ + Kind: TemplateGroupTemplateKindGrafana, + } } diff --git a/apps/alerting/notifications/pkg/apis/alertingnotifications_manifest.go b/apps/alerting/notifications/pkg/apis/alertingnotifications_manifest.go index e16f443a4f6..18447f62760 100644 --- a/apps/alerting/notifications/pkg/apis/alertingnotifications_manifest.go +++ b/apps/alerting/notifications/pkg/apis/alertingnotifications_manifest.go @@ -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"}}`) versionSchemaRoutingTreev0alpha1 app.VersionSchema _ = json.Unmarshal(rawSchemaRoutingTreev0alpha1, &versionSchemaRoutingTreev0alpha1) - 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"}}`) + 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"}}`) versionSchemaTemplateGroupv0alpha1 app.VersionSchema _ = 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"}}`) diff --git a/apps/alerting/rules/go.mod b/apps/alerting/rules/go.mod index 63da00536a6..45028a5bb0f 100644 --- a/apps/alerting/rules/go.mod +++ b/apps/alerting/rules/go.mod @@ -3,16 +3,16 @@ module github.com/grafana/grafana/apps/alerting/rules go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 - github.com/prometheus/common v0.67.3 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 + github.com/prometheus/common v0.67.4 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -22,13 +22,23 @@ require ( github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -37,7 +47,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -50,42 +60,42 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/alerting/rules/go.sum b/apps/alerting/rules/go.sum index 3df8e8b5ebe..e5233ba82c9 100644 --- a/apps/alerting/rules/go.sum +++ b/apps/alerting/rules/go.sum @@ -1,7 +1,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -23,14 +23,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -39,8 +65,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -48,10 +74,10 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -73,8 +99,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -95,8 +121,6 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -104,10 +128,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -122,30 +146,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -163,34 +187,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -199,39 +223,39 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/annotation/go.mod b/apps/annotation/go.mod index 946c42fe38f..aa4942ccd60 100644 --- a/apps/annotation/go.mod +++ b/apps/annotation/go.mod @@ -3,15 +3,15 @@ module github.com/grafana/grafana/apps/annotation go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -21,13 +21,23 @@ require ( github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -36,7 +46,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -49,43 +59,43 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/annotation/go.sum b/apps/annotation/go.sum index 3df8e8b5ebe..e5233ba82c9 100644 --- a/apps/annotation/go.sum +++ b/apps/annotation/go.sum @@ -1,7 +1,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -23,14 +23,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -39,8 +65,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -48,10 +74,10 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -73,8 +99,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -95,8 +121,6 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -104,10 +128,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -122,30 +146,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -163,34 +187,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -199,39 +223,39 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/collections/go.mod b/apps/collections/go.mod index 00575d7e6d4..05b9e33db99 100644 --- a/apps/collections/go.mod +++ b/apps/collections/go.mod @@ -3,11 +3,11 @@ module github.com/grafana/grafana/apps/collections go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 + github.com/grafana/grafana-app-sdk v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 github.com/stretchr/testify v1.11.1 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( @@ -18,19 +18,29 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.48.3 // indirect + github.com/google/gnostic-models v0.7.1 // indirect + github.com/grafana/grafana-app-sdk/logging v0.48.7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -41,28 +51,28 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/collections/go.sum b/apps/collections/go.sum index 75a19848d73..aa5de8cbe99 100644 --- a/apps/collections/go.sum +++ b/apps/collections/go.sum @@ -14,29 +14,55 @@ github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 h1:X0cnaFdR+iz+sDSuoZmkryFSjOirchHe2MdKSRwBWgM= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2/go.mod h1:RRvSjHH12/PnQaXraMO65jUhVu8n59mzvhfIMBETnV4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -58,8 +84,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -76,8 +102,6 @@ github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletI github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -85,10 +109,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -101,16 +125,16 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= @@ -126,24 +150,24 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -154,31 +178,31 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/collections/pkg/apis/collections/v1alpha1/stars.go b/apps/collections/pkg/apis/collections/v1alpha1/stars.go index e203e6b560e..79bff8a6513 100644 --- a/apps/collections/pkg/apis/collections/v1alpha1/stars.go +++ b/apps/collections/pkg/apis/collections/v1alpha1/stars.go @@ -8,9 +8,8 @@ import ( func (stars *StarsSpec) Add(group, kind, name string) { for i, r := range stars.Resource { if r.Group == group && r.Kind == kind { - r.Names = append(r.Names, name) - slices.Sort(r.Names) - stars.Resource[i].Names = slices.Compact(r.Names) + stars.Resource[i].Names = append(r.Names, name) + stars.Normalize() return } } @@ -46,8 +45,15 @@ func (stars *StarsSpec) Normalize() { resources := make([]StarsResource, 0, len(stars.Resource)) for _, r := range stars.Resource { if len(r.Names) > 0 { - slices.Sort(r.Names) - r.Names = slices.Compact(r.Names) // removes any duplicates + unique := make([]string, 0, len(r.Names)) + found := make(map[string]bool, len(r.Names)) + for _, name := range r.Names { + if !found[name] { + unique = append(unique, name) + found[name] = true + } + } + r.Names = unique resources = append(resources, r) } } diff --git a/apps/collections/pkg/apis/collections/v1alpha1/stars_test.go b/apps/collections/pkg/apis/collections/v1alpha1/stars_test.go index 5713b07a751..d4421fae614 100644 --- a/apps/collections/pkg/apis/collections/v1alpha1/stars_test.go +++ b/apps/collections/pkg/apis/collections/v1alpha1/stars_test.go @@ -39,7 +39,7 @@ func TestStarsWrite(t *testing.T) { Resource: []StarsResource{{ Group: "g", Kind: "k", - Names: []string{"a", "b", "c", "x"}, // added "b" (and sorted) + Names: []string{"a", "b", "x", "c"}, // added c to the end }}, }, }, { diff --git a/apps/correlations/go.mod b/apps/correlations/go.mod index 29bc91e70a6..388afc2fd38 100644 --- a/apps/correlations/go.mod +++ b/apps/correlations/go.mod @@ -3,15 +3,15 @@ module github.com/grafana/grafana/apps/correlations go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -21,13 +21,23 @@ require ( github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -36,7 +46,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -49,43 +59,43 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/correlations/go.sum b/apps/correlations/go.sum index 3df8e8b5ebe..e5233ba82c9 100644 --- a/apps/correlations/go.sum +++ b/apps/correlations/go.sum @@ -1,7 +1,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -23,14 +23,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -39,8 +65,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -48,10 +74,10 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -73,8 +99,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -95,8 +121,6 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -104,10 +128,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -122,30 +146,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -163,34 +187,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -199,39 +223,39 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/dashboard/go.mod b/apps/dashboard/go.mod index 0a19120fe80..86d5ec1ff09 100644 --- a/apps/dashboard/go.mod +++ b/apps/dashboard/go.mod @@ -5,16 +5,17 @@ go 1.25.5 require ( cuelang.org/go v0.11.1 github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana-plugin-sdk-go v0.284.0 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e + github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/prometheus/client_golang v1.23.2 github.com/stretchr/testify v1.11.1 - k8s.io/apimachinery v0.34.2 - k8s.io/apiserver v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 + k8s.io/apimachinery v0.34.3 + k8s.io/apiserver v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 ) require ( @@ -33,17 +34,27 @@ require ( github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/flatbuffers v25.2.10+incompatible // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect @@ -65,7 +76,7 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -79,55 +90,55 @@ require ( github.com/oklog/run v1.1.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pierrec/lz4/v4 v4.1.22 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.34.2 // indirect - k8s.io/component-base v0.34.2 // indirect + k8s.io/client-go v0.34.3 // indirect + k8s.io/component-base v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/dashboard/go.sum b/apps/dashboard/go.sum index 0faeaaf78ba..3bc70db5e6e 100644 --- a/apps/dashboard/go.sum +++ b/apps/dashboard/go.sum @@ -1,5 +1,5 @@ -cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 h1:R5wwEcbEZSBmeyg91MJZTxfd7WpBo2jPof3AYjRbxwY= -cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819 h1:Zh+Ur3OsoWpvALHPLT45nOekHkgOt+IOfutBbPqM17I= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819/go.mod h1:WjmQxb+W6nVNCgj8nXrF24lIz95AHwnSl36tpjDZSU8= cuelang.org/go v0.11.1 h1:pV+49MX1mmvDm8Qh3Za3M786cty8VKPWzQ1Ho4gZRP0= cuelang.org/go v0.11.1/go.mod h1:PBY6XvPUswPPJ2inpvUozP9mebDVTXaeehQikhZPBz0= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= @@ -28,8 +28,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY= -github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/proto v1.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I= +github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= @@ -47,14 +47,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -71,8 +97,8 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -85,10 +111,10 @@ github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGr github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4/go.mod h1:qeWYbnWzaYGl88JlL9+DsP1GT2Cudm58rLtx13fKZdw= 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/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad0a5JpEL4mH9ry7Ws= github.com/grafana/grafana-plugin-sdk-go v0.284.0/go.mod h1:lHPniaSxq3SL5MxDIPy04TYB1jnTp/ivkYO+xn5Rz3E= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e h1:BTKk7LHuG1kmAkucwTA7DuMbKpKvJTKrGdBmUNO4dfQ= @@ -112,6 +138,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= github.com/jaegertracing/jaeger-idl v0.5.0 h1:zFXR5NL3Utu7MhPg8ZorxtCBjHrL3ReM1VoB65FOFGE= @@ -140,8 +168,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM= github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -183,12 +211,12 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= -github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= -github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= @@ -202,12 +230,12 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b h1:fPVI9E6QNFYI0Ph3XpKUDrcAvbCifHvqYJcntFLPog8= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -229,8 +257,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -241,34 +269,34 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 h1:2pn7OzMewmYRiNtv1doZnLo3gONcnMHlFnmOR8Vgt+8= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0/go.mod h1:rjbQTDEPQymPE0YnRQp9/NuPwwtL0sesz/fnqRW/v84= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 h1:nXGeLvT1QtCAhkASkP/ksjkTKZALIaQBIW+JSIw1KIc= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0/go.mod h1:oMvOXk78ZR3KEuPMBgp/ThAMDy9ku/eyUVztr+3G6Wo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 h1:oPW/SRFyHgIgxrvNhSBzqvZER2N5kRlci3/rGTOuyWo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0/go.mod h1:B9Oka5QVD0bnmZNO6gBbBta6nohD/1Z+f9waH2oXyBs= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -280,25 +308,25 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -309,24 +337,24 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -335,42 +363,42 @@ golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhS golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= -k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ= -k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/component-base v0.34.3 h1:zsEgw6ELqK0XncCQomgO9DpUIzlrYuZYA0Cgo+JWpVk= +k8s.io/component-base v0.34.3/go.mod h1:5iIlD8wPfWE/xSHTRfbjuvUul2WZbI2nOUK65XL0E/c= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue index 3fe93d7305f..6488de41c96 100644 --- a/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue +++ b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue @@ -129,7 +129,7 @@ DashboardLink: { placement?: DashboardLinkPlacement } -// Dashboard Link placement. Defines where the link should be displayed. +// Dashboard Link placement. Defines where the link should be displayed. // - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu DashboardLinkPlacement: "inControlsMenu" @@ -768,6 +768,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged" // Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing). VariableHide: *"dontHide" | "hideLabel" | "hideVariable" +// Determine whether regex applies to variable value or display text +// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users) +VariableRegexApplyTo: *"value" | "text" + // Determine the origin of the adhoc variable filter FilterOrigin: "dashboard" @@ -803,6 +807,7 @@ QueryVariableSpec: { datasource?: DataSourceRef query: DataQueryKind regex: string | *"" + regexApplyTo?: VariableRegexApplyTo sort: VariableSort definition?: string options: [...VariableOption] | *[] @@ -927,6 +932,7 @@ CustomVariableSpec: { skipUrlSync: bool | *false description?: string allowCustomValue: bool | *true + valuesFormat?: "csv" | "json" } // Custom variable kind diff --git a/apps/dashboard/kinds/v2beta1/dashboard_spec.cue b/apps/dashboard/kinds/v2beta1/dashboard_spec.cue index ef4a27fd6b7..a8e1f121213 100644 --- a/apps/dashboard/kinds/v2beta1/dashboard_spec.cue +++ b/apps/dashboard/kinds/v2beta1/dashboard_spec.cue @@ -772,6 +772,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged" // Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing), `inControlsMenu` (show in a drop-down menu). VariableHide: *"dontHide" | "hideLabel" | "hideVariable" | "inControlsMenu" +// Determine whether regex applies to variable value or display text +// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users) +VariableRegexApplyTo: *"value" | "text" + // Determine the origin of the adhoc variable filter FilterOrigin: "dashboard" @@ -806,6 +810,7 @@ QueryVariableSpec: { description?: string query: DataQueryKind regex: string | *"" + regexApplyTo?: VariableRegexApplyTo sort: VariableSort definition?: string options: [...VariableOption] | *[] @@ -930,6 +935,7 @@ CustomVariableSpec: { skipUrlSync: bool | *false description?: string allowCustomValue: bool | *true + valuesFormat?: "csv" | "json" } // Custom variable kind diff --git a/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue b/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue index d2a65bbbf24..3c6c0e92355 100644 --- a/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue +++ b/apps/dashboard/pkg/apis/dashboard/v0alpha1/dashboard_kind.cue @@ -222,6 +222,10 @@ lineage: schemas: [{ // 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. regex?: string + // Optional, indicates whether a custom type variable uses CSV or JSON to define its values + valuesFormat?: "csv" | "json" | *"csv" + // Determine whether regex applies to variable value or display text + regexApplyTo?: #VariableRegexApplyTo // Additional static options for query variable staticOptions?: [...#VariableOption] // Ordering of static options in relation to options returned from data source for query variable @@ -249,6 +253,10 @@ lineage: schemas: [{ // Accepted values are 0 (show label and value), 1 (show value only), 2 (show nothing), 3 (show under the controls dropdown menu). #VariableHide: 0 | 1 | 2 | 3 @cuetsy(kind="enum",memberNames="dontHide|hideLabel|hideVariable|inControlsMenu") @grafana(TSVeneer="type") + // Determine whether regex applies to variable value or display text + // Accepted values are "value" (apply to value used in queries) or "text" (apply to display text shown to users) + #VariableRegexApplyTo: "value" | "text" @cuetsy(kind="type") + // Sort variable options // Accepted values are: // `0`: No sorting @@ -700,6 +708,10 @@ lineage: schemas: [{ // Field options allow you to change how the data is displayed in your visualizations. fieldConfig?: #FieldConfigSource + + // When a panel is migrated from a previous version (Angular to React), this field is set to the original panel type. + // This is used to determine the original panel type when migrating to a new version so the plugin migration can be applied. + autoMigrateFrom?: string } @cuetsy(kind="interface") @grafana(TSVeneer="type") @grafanamaturity(NeedsExpertReview) // The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. diff --git a/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue b/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue index d2a65bbbf24..3c6c0e92355 100644 --- a/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue +++ b/apps/dashboard/pkg/apis/dashboard/v1beta1/dashboard_kind.cue @@ -222,6 +222,10 @@ lineage: schemas: [{ // 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. regex?: string + // Optional, indicates whether a custom type variable uses CSV or JSON to define its values + valuesFormat?: "csv" | "json" | *"csv" + // Determine whether regex applies to variable value or display text + regexApplyTo?: #VariableRegexApplyTo // Additional static options for query variable staticOptions?: [...#VariableOption] // Ordering of static options in relation to options returned from data source for query variable @@ -249,6 +253,10 @@ lineage: schemas: [{ // Accepted values are 0 (show label and value), 1 (show value only), 2 (show nothing), 3 (show under the controls dropdown menu). #VariableHide: 0 | 1 | 2 | 3 @cuetsy(kind="enum",memberNames="dontHide|hideLabel|hideVariable|inControlsMenu") @grafana(TSVeneer="type") + // Determine whether regex applies to variable value or display text + // Accepted values are "value" (apply to value used in queries) or "text" (apply to display text shown to users) + #VariableRegexApplyTo: "value" | "text" @cuetsy(kind="type") + // Sort variable options // Accepted values are: // `0`: No sorting @@ -700,6 +708,10 @@ lineage: schemas: [{ // Field options allow you to change how the data is displayed in your visualizations. fieldConfig?: #FieldConfigSource + + // When a panel is migrated from a previous version (Angular to React), this field is set to the original panel type. + // This is used to determine the original panel type when migrating to a new version so the plugin migration can be applied. + autoMigrateFrom?: string } @cuetsy(kind="interface") @grafana(TSVeneer="type") @grafanamaturity(NeedsExpertReview) // The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue index d822ad9f38a..2b027ff98e1 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec.cue @@ -133,7 +133,7 @@ DashboardLink: { placement?: DashboardLinkPlacement } -// Dashboard Link placement. Defines where the link should be displayed. +// Dashboard Link placement. Defines where the link should be displayed. // - "inControlsMenu" renders the link in bottom part of the dashboard controls dropdown menu DashboardLinkPlacement: "inControlsMenu" @@ -772,6 +772,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged" // Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing). VariableHide: *"dontHide" | "hideLabel" | "hideVariable" +// Determine whether regex applies to variable value or display text +// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users) +VariableRegexApplyTo: *"value" | "text" + // Determine the origin of the adhoc variable filter FilterOrigin: "dashboard" @@ -807,6 +811,7 @@ QueryVariableSpec: { datasource?: DataSourceRef query: DataQueryKind regex: string | *"" + regexApplyTo?: VariableRegexApplyTo sort: VariableSort definition?: string options: [...VariableOption] | *[] @@ -931,6 +936,7 @@ CustomVariableSpec: { skipUrlSync: bool | *false description?: string allowCustomValue: bool | *true + valuesFormat?: "csv" | "json" } // Custom variable kind diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go index 625c6fe17c0..3f594306ef5 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go @@ -1364,6 +1364,7 @@ type DashboardQueryVariableSpec struct { Datasource *DashboardDataSourceRef `json:"datasource,omitempty"` Query DashboardDataQueryKind `json:"query"` Regex string `json:"regex"` + RegexApplyTo *DashboardVariableRegexApplyTo `json:"regexApplyTo,omitempty"` Sort DashboardVariableSort `json:"sort"` Definition *string `json:"definition,omitempty"` Options []DashboardVariableOption `json:"options"` @@ -1393,6 +1394,7 @@ func NewDashboardQueryVariableSpec() *DashboardQueryVariableSpec { SkipUrlSync: false, Query: *NewDashboardDataQueryKind(), Regex: "", + RegexApplyTo: (func(input DashboardVariableRegexApplyTo) *DashboardVariableRegexApplyTo { return &input })(DashboardVariableRegexApplyToValue), Options: []DashboardVariableOption{}, Multi: false, IncludeAll: false, @@ -1443,6 +1445,16 @@ const ( DashboardVariableRefreshOnTimeRangeChanged DashboardVariableRefresh = "onTimeRangeChanged" ) +// Determine whether regex applies to variable value or display text +// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users) +// +k8s:openapi-gen=true +type DashboardVariableRegexApplyTo string + +const ( + DashboardVariableRegexApplyToValue DashboardVariableRegexApplyTo = "value" + DashboardVariableRegexApplyToText DashboardVariableRegexApplyTo = "text" +) + // Sort variable options // Accepted values are: // `disabled`: No sorting @@ -1691,18 +1703,19 @@ func NewDashboardCustomVariableKind() *DashboardCustomVariableKind { // Custom variable specification // +k8s:openapi-gen=true type DashboardCustomVariableSpec struct { - Name string `json:"name"` - Query string `json:"query"` - Current DashboardVariableOption `json:"current"` - Options []DashboardVariableOption `json:"options"` - Multi bool `json:"multi"` - IncludeAll bool `json:"includeAll"` - AllValue *string `json:"allValue,omitempty"` - Label *string `json:"label,omitempty"` - Hide DashboardVariableHide `json:"hide"` - SkipUrlSync bool `json:"skipUrlSync"` - Description *string `json:"description,omitempty"` - AllowCustomValue bool `json:"allowCustomValue"` + Name string `json:"name"` + Query string `json:"query"` + Current DashboardVariableOption `json:"current"` + Options []DashboardVariableOption `json:"options"` + Multi bool `json:"multi"` + IncludeAll bool `json:"includeAll"` + AllValue *string `json:"allValue,omitempty"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` + AllowCustomValue bool `json:"allowCustomValue"` + ValuesFormat *DashboardCustomVariableSpecValuesFormat `json:"valuesFormat,omitempty"` } // NewDashboardCustomVariableSpec creates a new DashboardCustomVariableSpec object. @@ -2086,6 +2099,14 @@ const ( DashboardQueryVariableSpecStaticOptionsOrderSorted DashboardQueryVariableSpecStaticOptionsOrder = "sorted" ) +// +k8s:openapi-gen=true +type DashboardCustomVariableSpecValuesFormat string + +const ( + DashboardCustomVariableSpecValuesFormatCsv DashboardCustomVariableSpecValuesFormat = "csv" + DashboardCustomVariableSpecValuesFormatJson DashboardCustomVariableSpecValuesFormat = "json" +) + // +k8s:openapi-gen=true type DashboardPanelKindOrLibraryPanelKind struct { PanelKind *DashboardPanelKind `json:"PanelKind,omitempty"` diff --git a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go index ff7429d7c2b..4c6f3f5ed20 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go +++ b/apps/dashboard/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go @@ -1548,6 +1548,12 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardCustomVariableSpec(ref common.R Format: "", }, }, + "valuesFormat": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"name", "query", "current", "options", "multi", "includeAll", "hide", "skipUrlSync", "allowCustomValue"}, }, @@ -3646,6 +3652,12 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableSpec(ref common.Re Format: "", }, }, + "regexApplyTo": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, "sort": { SchemaProps: spec.SchemaProps{ Default: "", diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue index 0c061075e6d..375ba67f003 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec.cue @@ -776,6 +776,10 @@ VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged" // Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing), `inControlsMenu` (show in a drop-down menu). VariableHide: *"dontHide" | "hideLabel" | "hideVariable" | "inControlsMenu" +// Determine whether regex applies to variable value or display text +// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users) +VariableRegexApplyTo: *"value" | "text" + // Determine the origin of the adhoc variable filter FilterOrigin: "dashboard" @@ -810,6 +814,7 @@ QueryVariableSpec: { description?: string query: DataQueryKind regex: string | *"" + regexApplyTo?: VariableRegexApplyTo sort: VariableSort definition?: string options: [...VariableOption] | *[] @@ -934,6 +939,7 @@ CustomVariableSpec: { skipUrlSync: bool | *false description?: string allowCustomValue: bool | *true + valuesFormat?: "csv" | "json" } // Custom variable kind diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go index a6e63aa0bcc..96054cb2fc4 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/dashboard_spec_gen.go @@ -1367,6 +1367,7 @@ type DashboardQueryVariableSpec struct { Description *string `json:"description,omitempty"` Query DashboardDataQueryKind `json:"query"` Regex string `json:"regex"` + RegexApplyTo *DashboardVariableRegexApplyTo `json:"regexApplyTo,omitempty"` Sort DashboardVariableSort `json:"sort"` Definition *string `json:"definition,omitempty"` Options []DashboardVariableOption `json:"options"` @@ -1396,6 +1397,7 @@ func NewDashboardQueryVariableSpec() *DashboardQueryVariableSpec { SkipUrlSync: false, Query: *NewDashboardDataQueryKind(), Regex: "", + RegexApplyTo: (func(input DashboardVariableRegexApplyTo) *DashboardVariableRegexApplyTo { return &input })(DashboardVariableRegexApplyToValue), Options: []DashboardVariableOption{}, Multi: false, IncludeAll: false, @@ -1447,6 +1449,16 @@ const ( DashboardVariableRefreshOnTimeRangeChanged DashboardVariableRefresh = "onTimeRangeChanged" ) +// Determine whether regex applies to variable value or display text +// Accepted values are `value` (apply to value used in queries) or `text` (apply to display text shown to users) +// +k8s:openapi-gen=true +type DashboardVariableRegexApplyTo string + +const ( + DashboardVariableRegexApplyToValue DashboardVariableRegexApplyTo = "value" + DashboardVariableRegexApplyToText DashboardVariableRegexApplyTo = "text" +) + // Sort variable options // Accepted values are: // `disabled`: No sorting @@ -1695,18 +1707,19 @@ func NewDashboardCustomVariableKind() *DashboardCustomVariableKind { // Custom variable specification // +k8s:openapi-gen=true type DashboardCustomVariableSpec struct { - Name string `json:"name"` - Query string `json:"query"` - Current DashboardVariableOption `json:"current"` - Options []DashboardVariableOption `json:"options"` - Multi bool `json:"multi"` - IncludeAll bool `json:"includeAll"` - AllValue *string `json:"allValue,omitempty"` - Label *string `json:"label,omitempty"` - Hide DashboardVariableHide `json:"hide"` - SkipUrlSync bool `json:"skipUrlSync"` - Description *string `json:"description,omitempty"` - AllowCustomValue bool `json:"allowCustomValue"` + Name string `json:"name"` + Query string `json:"query"` + Current DashboardVariableOption `json:"current"` + Options []DashboardVariableOption `json:"options"` + Multi bool `json:"multi"` + IncludeAll bool `json:"includeAll"` + AllValue *string `json:"allValue,omitempty"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` + AllowCustomValue bool `json:"allowCustomValue"` + ValuesFormat *DashboardCustomVariableSpecValuesFormat `json:"valuesFormat,omitempty"` } // NewDashboardCustomVariableSpec creates a new DashboardCustomVariableSpec object. @@ -2121,6 +2134,14 @@ const ( DashboardQueryVariableSpecStaticOptionsOrderSorted DashboardQueryVariableSpecStaticOptionsOrder = "sorted" ) +// +k8s:openapi-gen=true +type DashboardCustomVariableSpecValuesFormat string + +const ( + DashboardCustomVariableSpecValuesFormatCsv DashboardCustomVariableSpecValuesFormat = "csv" + DashboardCustomVariableSpecValuesFormatJson DashboardCustomVariableSpecValuesFormat = "json" +) + // +k8s:openapi-gen=true type DashboardPanelKindOrLibraryPanelKind struct { PanelKind *DashboardPanelKind `json:"PanelKind,omitempty"` diff --git a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go index 3a129374192..402810f6e53 100644 --- a/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go +++ b/apps/dashboard/pkg/apis/dashboard/v2beta1/zz_generated.openapi.go @@ -1560,6 +1560,12 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardCustomVariableSpec(ref common.Re Format: "", }, }, + "valuesFormat": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"name", "query", "current", "options", "multi", "includeAll", "hide", "skipUrlSync", "allowCustomValue"}, }, @@ -3656,6 +3662,12 @@ func schema_pkg_apis_dashboard_v2beta1_DashboardQueryVariableSpec(ref common.Ref Format: "", }, }, + "regexApplyTo": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, "sort": { SchemaProps: spec.SchemaProps{ Default: "", diff --git a/apps/dashboard/pkg/apis/dashboard_manifest.go b/apps/dashboard/pkg/apis/dashboard_manifest.go index c4e35bd8f40..e94d66fec82 100644 --- a/apps/dashboard/pkg/apis/dashboard_manifest.go +++ b/apps/dashboard/pkg/apis/dashboard_manifest.go @@ -32,10 +32,10 @@ var ( rawSchemaDashboardv1beta1 = []byte(`{"ConversionStatus":{"additionalProperties":false,"description":"ConversionStatus is the status of the conversion of the dashboard.","properties":{"error":{"description":"The error message from the conversion.\nEmpty if the conversion has not failed.","type":"string"},"failed":{"description":"Whether from another version has failed.\nIf true, means that the dashboard is not valid,\nand the caller should instead fetch the stored version.","type":"boolean"},"source":{"additionalProperties":{},"description":"The original value map[string]any","type":"object"},"storedVersion":{"description":"The version which was stored when the dashboard was created / updated.\nFetching this version should always succeed.","type":"string"}},"required":["failed"],"type":"object"},"Dashboard":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"spec":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"status":{"additionalProperties":false,"properties":{"conversion":{"$ref":"#/components/schemas/ConversionStatus","description":"Optional conversion status."}},"type":"object"}}`) versionSchemaDashboardv1beta1 app.VersionSchema _ = json.Unmarshal(rawSchemaDashboardv1beta1, &versionSchemaDashboardv1beta1) - rawSchemaDashboardv2alpha1 = []byte(`{"Action":{"additionalProperties":false,"properties":{"confirmation":{"type":"string"},"fetch":{"$ref":"#/components/schemas/FetchOptions"},"infinity":{"$ref":"#/components/schemas/InfinityOptions"},"oneClick":{"type":"boolean"},"style":{"additionalProperties":false,"properties":{"backgroundColor":{"type":"string"}},"type":"object"},"title":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionType"},"variables":{"items":{"$ref":"#/components/schemas/ActionVariable"},"type":"array"}},"required":["type","title"],"type":"object"},"ActionType":{"enum":["fetch","infinity"],"type":"string"},"ActionVariable":{"additionalProperties":false,"properties":{"key":{"type":"string"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionVariableType"}},"required":["key","name","type"],"type":"object"},"ActionVariableType":{"const":"string","description":"Action variable type","type":"string"},"AdHocFilterWithLabels":{"additionalProperties":false,"description":"Define the AdHocFilterWithLabels type","properties":{"condition":{"description":"@deprecated","type":"string"},"forceEdit":{"type":"boolean"},"key":{"type":"string"},"keyLabel":{"type":"string"},"operator":{"type":"string"},"origin":{"$ref":"#/components/schemas/FilterOrigin"},"value":{"type":"string"},"valueLabels":{"items":{"type":"string"},"type":"array"},"values":{"items":{"type":"string"},"type":"array"}},"required":["key","operator","value"],"type":"object"},"AdhocVariableKind":{"additionalProperties":false,"description":"Adhoc variable kind","properties":{"kind":{"const":"AdhocVariable","type":"string"},"spec":{"$ref":"#/components/schemas/AdhocVariableSpec"}},"required":["kind","spec"],"type":"object"},"AdhocVariableSpec":{"additionalProperties":false,"description":"Adhoc variable specification","properties":{"allowCustomValue":{"default":true,"type":"boolean"},"baseFilters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"defaultKeys":{"items":{"$ref":"#/components/schemas/MetricFindValue"},"type":"array"},"description":{"type":"string"},"filters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","baseFilters","filters","defaultKeys","hide","skipUrlSync","allowCustomValue"],"type":"object"},"AnnotationEventFieldMapping":{"additionalProperties":false,"description":"Annotation event field mapping. Defines how to map a data frame field to an annotation event field.","properties":{"regex":{"description":"Regular expression to apply to the field value","type":"string"},"source":{"default":"field","description":"Source type for the field value","type":"string"},"value":{"description":"Constant value to use when source is \"text\"","type":"string"}},"type":"object"},"AnnotationPanelFilter":{"additionalProperties":false,"properties":{"exclude":{"default":false,"description":"Should the specified panels be included or excluded","type":"boolean"},"ids":{"description":"Panel IDs that should be included or excluded","items":{"type":"integer"},"type":"array"}},"required":["ids"],"type":"object"},"AnnotationQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"AnnotationQuery","type":"string"},"spec":{"$ref":"#/components/schemas/AnnotationQuerySpec"}},"required":["kind","spec"],"type":"object"},"AnnotationQuerySpec":{"additionalProperties":false,"properties":{"builtIn":{"default":false,"type":"boolean"},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"enable":{"type":"boolean"},"filter":{"$ref":"#/components/schemas/AnnotationPanelFilter"},"hide":{"type":"boolean"},"iconColor":{"type":"string"},"legacyOptions":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"Catch-all field for datasource-specific properties","type":"object"},"mappings":{"additionalProperties":{"$ref":"#/components/schemas/AnnotationEventFieldMapping"},"description":"Mappings define how to convert data frame fields to annotation event fields.","type":"object"},"name":{"type":"string"},"query":{"$ref":"#/components/schemas/DataQueryKind"}},"required":["enable","hide","iconColor","name"],"type":"object"},"AutoGridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutItemSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"element":{"$ref":"#/components/schemas/ElementReference"},"repeat":{"$ref":"#/components/schemas/AutoGridRepeatOptions"}},"required":["element"],"type":"object"},"AutoGridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutSpec":{"additionalProperties":false,"properties":{"columnWidth":{"type":"number"},"columnWidthMode":{"default":"standard","enum":["narrow","standard","wide","custom"],"type":"string"},"fillScreen":{"default":false,"type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/AutoGridLayoutItemKind"},"type":"array"},"maxColumnCount":{"default":3,"type":"number"},"rowHeight":{"type":"number"},"rowHeightMode":{"default":"standard","enum":["short","standard","tall","custom"],"type":"string"}},"required":["columnWidthMode","rowHeightMode","items"],"type":"object"},"AutoGridRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"ConditionalRenderingDataKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingData","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingDataSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingDataSpec":{"additionalProperties":false,"properties":{"value":{"type":"boolean"}},"required":["value"],"type":"object"},"ConditionalRenderingGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingGroup","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingGroupSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingGroupSpec":{"additionalProperties":false,"properties":{"condition":{"enum":["and","or"],"type":"string"},"items":{"items":{"oneOf":[{"$ref":"#/components/schemas/ConditionalRenderingVariableKind"},{"$ref":"#/components/schemas/ConditionalRenderingDataKind"},{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeKind"}]},"type":"array"},"visibility":{"enum":["show","hide"],"type":"string"}},"required":["visibility","condition","items"],"type":"object"},"ConditionalRenderingTimeRangeSizeKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingTimeRangeSize","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingTimeRangeSizeSpec":{"additionalProperties":false,"properties":{"value":{"type":"string"}},"required":["value"],"type":"object"},"ConditionalRenderingVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingVariableSpec":{"additionalProperties":false,"properties":{"operator":{"enum":["equals","notEquals","matches","notMatches"],"type":"string"},"value":{"type":"string"},"variable":{"type":"string"}},"required":["variable","operator","value"],"type":"object"},"ConstantVariableKind":{"additionalProperties":false,"description":"Constant variable kind","properties":{"kind":{"const":"ConstantVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConstantVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConstantVariableSpec":{"additionalProperties":false,"description":"Constant variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","hide","skipUrlSync"],"type":"object"},"ConversionStatus":{"additionalProperties":false,"description":"ConversionStatus is the status of the conversion of the dashboard.","properties":{"error":{"description":"The error message from the conversion.\nEmpty if the conversion has not failed.","type":"string"},"failed":{"description":"Whether from another version has failed.\nIf true, means that the dashboard is not valid,\nand the caller should instead fetch the stored version.","type":"boolean"},"source":{"additionalProperties":{},"description":"The original value map[string]any","type":"object"},"storedVersion":{"description":"The version which was stored when the dashboard was created / updated.\nFetching this version should always succeed.","type":"string"}},"required":["failed"],"type":"object"},"CustomVariableKind":{"additionalProperties":false,"description":"Custom variable kind","properties":{"kind":{"const":"CustomVariable","type":"string"},"spec":{"$ref":"#/components/schemas/CustomVariableSpec"}},"required":["kind","spec"],"type":"object"},"CustomVariableSpec":{"additionalProperties":false,"description":"Custom variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"Dashboard":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"DashboardCursorSync":{"description":"\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip.","enum":["Crosshair","Tooltip","Off"],"type":"string"},"DashboardLink":{"additionalProperties":false,"description":"Links with references to other dashboards or external resources","properties":{"asDropdown":{"default":false,"description":"If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards","type":"boolean"},"icon":{"description":"Icon name to be displayed with the link","type":"string"},"includeVars":{"default":false,"description":"If true, includes current template variables values in the link as query params","type":"boolean"},"keepTime":{"default":false,"description":"If true, includes current time range in the link as query params","type":"boolean"},"placement":{"$ref":"#/components/schemas/DashboardLinkPlacement","description":"Placement can be used to display the link somewhere else on the dashboard other than above the visualisations."},"tags":{"description":"List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards","items":{"type":"string"},"type":"array"},"targetBlank":{"default":false,"description":"If true, the link will be opened in a new tab","type":"boolean"},"title":{"description":"Title to display with the link","type":"string"},"tooltip":{"description":"Tooltip to display when the user hovers their mouse over it","type":"string"},"type":{"$ref":"#/components/schemas/DashboardLinkType","description":"Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)\nFIXME: The type is generated as ` + "`" + `type: DashboardLinkType | dashboardLinkType.Link;` + "`" + ` but it should be ` + "`" + `type: DashboardLinkType` + "`" + `"},"url":{"description":"Link URL. Only required/valid if the type is link","type":"string"}},"required":["title","type","icon","tooltip","tags","asDropdown","targetBlank","includeVars","keepTime"],"type":"object"},"DashboardLinkPlacement":{"const":"inControlsMenu","description":"Dashboard Link placement. Defines where the link should be displayed.\n- \"inControlsMenu\" renders the link in bottom part of the dashboard controls dropdown menu","type":"string"},"DashboardLinkType":{"description":"Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)","enum":["link","dashboards"],"type":"string"},"DataLink":{"additionalProperties":false,"properties":{"targetBlank":{"type":"boolean"},"title":{"type":"string"},"url":{"type":"string"}},"required":["title","url"],"type":"object"},"DataQueryKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a DataQueryKind is the datasource type","type":"string"},"spec":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"}},"required":["kind","spec"],"type":"object"},"DataSourceRef":{"additionalProperties":false,"properties":{"type":{"description":"The plugin type-id","type":"string"},"uid":{"description":"Specific datasource instance","type":"string"}},"type":"object"},"DataTopic":{"description":"A topic is attached to DataFrame metadata in query results.\nThis specifies where the data should be used.","enum":["series","annotations","alertStates"],"type":"string"},"DataTransformerConfig":{"additionalProperties":false,"description":"Transformations allow to manipulate data returned by a query before the system applies a visualization.\nUsing transformations you can: rename fields, join time series data, perform mathematical operations across queries,\nuse the output of one transformation as the input to another transformation, etc.","properties":{"disabled":{"description":"Disabled transformations are skipped","type":"boolean"},"filter":{"$ref":"#/components/schemas/MatcherConfig","description":"Optional frame matcher. When missing it will be applied to all results"},"id":{"description":"Unique identifier of transformer","type":"string"},"options":{"additionalProperties":{},"description":"Options to be passed to the transformer\nValid options depend on the transformer id","type":"object"},"topic":{"$ref":"#/components/schemas/DataTopic","description":"Where to pull DataFrames from as input to transformation"}},"required":["id","options"],"type":"object"},"DatasourceVariableKind":{"additionalProperties":false,"description":"Datasource variable kind","properties":{"kind":{"const":"DatasourceVariable","type":"string"},"spec":{"$ref":"#/components/schemas/DatasourceVariableSpec"}},"required":["kind","spec"],"type":"object"},"DatasourceVariableSpec":{"additionalProperties":false,"description":"Datasource variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"pluginId":{"default":"","type":"string"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","pluginId","refresh","regex","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"DynamicConfigValue":{"additionalProperties":false,"properties":{"id":{"default":"","type":"string"},"value":{"additionalProperties":{},"type":"object"}},"required":["id"],"type":"object"},"Element":{"description":"Supported dashboard elements\n|* more element types in the future","oneOf":[{"$ref":"#/components/schemas/PanelKind"},{"$ref":"#/components/schemas/LibraryPanelKind"}]},"ElementReference":{"additionalProperties":false,"properties":{"kind":{"const":"ElementReference","type":"string"},"name":{"type":"string"}},"required":["kind","name"],"type":"object"},"FetchOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url"],"type":"object"},"FieldColor":{"additionalProperties":false,"description":"Map a field to a color.","properties":{"fixedColor":{"description":"The fixed color value for fixed or shades color modes.","type":"string"},"mode":{"$ref":"#/components/schemas/FieldColorModeId","description":"The main color scheme mode."},"seriesBy":{"$ref":"#/components/schemas/FieldColorSeriesByMode","description":"Some visualizations need to know how to assign a series color from by value color schemes."}},"required":["mode"],"type":"object"},"FieldColorModeId":{"description":"Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value.\nContinuous color interpolates a color using the percentage of a value relative to min and max.\nAccepted values are:\n` + "`" + `thresholds` + "`" + `: From thresholds. Informs Grafana to take the color from the matching threshold\n` + "`" + `palette-classic` + "`" + `: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `palette-classic-by-name` + "`" + `: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `continuous-viridis` + "`" + `: Continuous Viridis palette mode\n` + "`" + `continuous-magma` + "`" + `: Continuous Magma palette mode\n` + "`" + `continuous-plasma` + "`" + `: Continuous Plasma palette mode\n` + "`" + `continuous-inferno` + "`" + `: Continuous Inferno palette mode\n` + "`" + `continuous-cividis` + "`" + `: Continuous Cividis palette mode\n` + "`" + `continuous-GrYlRd` + "`" + `: Continuous Green-Yellow-Red palette mode\n` + "`" + `continuous-RdYlGr` + "`" + `: Continuous Red-Yellow-Green palette mode\n` + "`" + `continuous-BlYlRd` + "`" + `: Continuous Blue-Yellow-Red palette mode\n` + "`" + `continuous-YlRd` + "`" + `: Continuous Yellow-Red palette mode\n` + "`" + `continuous-BlPu` + "`" + `: Continuous Blue-Purple palette mode\n` + "`" + `continuous-YlBl` + "`" + `: Continuous Yellow-Blue palette mode\n` + "`" + `continuous-blues` + "`" + `: Continuous Blue palette mode\n` + "`" + `continuous-reds` + "`" + `: Continuous Red palette mode\n` + "`" + `continuous-greens` + "`" + `: Continuous Green palette mode\n` + "`" + `continuous-purples` + "`" + `: Continuous Purple palette mode\n` + "`" + `shades` + "`" + `: Shades of a single color. Specify a single color, useful in an override rule.\n` + "`" + `fixed` + "`" + `: Fixed color mode. Specify a single color, useful in an override rule.","enum":["thresholds","palette-classic","palette-classic-by-name","continuous-viridis","continuous-magma","continuous-plasma","continuous-inferno","continuous-cividis","continuous-GrYlRd","continuous-RdYlGr","continuous-BlYlRd","continuous-YlRd","continuous-BlPu","continuous-YlBl","continuous-blues","continuous-reds","continuous-greens","continuous-purples","fixed","shades"],"type":"string"},"FieldColorSeriesByMode":{"description":"Defines how to assign a series color from \"by value\" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value.","enum":["min","max","last"],"type":"string"},"FieldConfig":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"actions":{"description":"Define interactive HTTP requests that can be triggered from data visualizations.","items":{"$ref":"#/components/schemas/Action"},"type":"array"},"color":{"$ref":"#/components/schemas/FieldColor","description":"Panel color configuration"},"custom":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"custom is specified by the FieldConfig field\nin panel plugin schemas.","type":"object"},"decimals":{"description":"Specify the number of decimals Grafana includes in the rendered value.\nIf you leave this field blank, Grafana automatically truncates the number of decimals based on the value.\nFor example 1.1234 will display as 1.12 and 100.456 will display as 100.\nTo display all decimals, set the unit to ` + "`" + `String` + "`" + `.","type":"number"},"description":{"description":"Human readable field metadata","type":"string"},"displayName":{"description":"The display value for this field. This supports template variables blank is auto","type":"string"},"displayNameFromDS":{"description":"This can be used by data sources that return and explicit naming structure for values and labels\nWhen this property is configured, this value is used rather than the default naming strategy.","type":"string"},"filterable":{"description":"True if data source field supports ad-hoc filters","type":"boolean"},"links":{"description":"The behavior when clicking on a result","items":{"additionalProperties":{},"type":"object"},"type":"array"},"mappings":{"description":"Convert input values into a display string","items":{"$ref":"#/components/schemas/ValueMapping"},"type":"array"},"max":{"description":"The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"min":{"description":"The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"noValue":{"description":"Alternative to empty string","type":"string"},"path":{"description":"An explicit path to the field in the datasource. When the frame meta includes a path,\nThis will default to ` + "`" + `${frame.meta.path}/${field.name}\n\nWhen defined, this value can be used as an identifier within the datasource scope, and\nmay be used to update the results","type":"string"},"thresholds":{"$ref":"#/components/schemas/ThresholdsConfig","description":"Map numeric values to states"},"unit":{"description":"Unit a field should use. The unit you select is applied to all fields except time.\nYou can use the units ID availables in Grafana or a custom unit.\nAvailable units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts\nAs custom unit, you can use the following formats:\n` + "`" + `suffix:\u003csuffix\u003e` + "`" + ` for custom unit that should go after value.\n` + "`" + `prefix:\u003cprefix\u003e` + "`" + ` for custom unit that should go before value.\n` + "`" + `time:\u003cformat\u003e` + "`" + ` For custom date time formats type for example ` + "`" + `time:YYYY-MM-DD` + "`" + `.\n` + "`" + `si:\u003cbase scale\u003e\u003cunit characters\u003e` + "`" + ` for custom SI units. For example: ` + "`" + `si: mF` + "`" + `. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.\n` + "`" + `count:\u003cunit\u003e` + "`" + ` for a custom count unit.\n` + "`" + `currency:\u003cunit\u003e` + "`" + ` for custom a currency unit.","type":"string"},"writeable":{"description":"True if data source can write a value to the path. Auth/authz are supported separately","type":"boolean"}},"type":"object"},"FieldConfigSource":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"defaults":{"$ref":"#/components/schemas/FieldConfig","description":"Defaults are the options applied to all fields."},"overrides":{"description":"Overrides are the options applied to specific fields overriding the defaults.","items":{"additionalProperties":false,"properties":{"__systemRef":{"description":"Describes config override rules created when interacting with Grafana.","type":"string"},"matcher":{"$ref":"#/components/schemas/MatcherConfig"},"properties":{"items":{"$ref":"#/components/schemas/DynamicConfigValue"},"type":"array"}},"required":["matcher","properties"],"type":"object"},"type":"array"}},"required":["defaults","overrides"],"type":"object"},"FilterOrigin":{"const":"dashboard","description":"Determine the origin of the adhoc variable filter","type":"string"},"GridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutItemSpec":{"additionalProperties":false,"properties":{"element":{"$ref":"#/components/schemas/ElementReference","description":"reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference"},"height":{"type":"integer"},"repeat":{"$ref":"#/components/schemas/RepeatOptions"},"width":{"type":"integer"},"x":{"type":"integer"},"y":{"type":"integer"}},"required":["x","y","width","height","element"],"type":"object"},"GridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutSpec":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/GridLayoutItemKind"},"type":"array"}},"required":["items"],"type":"object"},"GroupByVariableKind":{"additionalProperties":false,"description":"Group variable kind","properties":{"kind":{"const":"GroupByVariable","type":"string"},"spec":{"$ref":"#/components/schemas/GroupByVariableSpec"}},"required":["kind","spec"],"type":"object"},"GroupByVariableSpec":{"additionalProperties":false,"description":"GroupBy variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"defaultValue":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","options","multi","hide","skipUrlSync"],"type":"object"},"HttpRequestMethod":{"enum":["GET","PUT","POST","DELETE","PATCH"],"type":"string"},"InfinityOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"datasourceUid":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url","datasourceUid"],"type":"object"},"IntervalVariableKind":{"additionalProperties":false,"description":"Interval variable kind","properties":{"kind":{"const":"IntervalVariable","type":"string"},"spec":{"$ref":"#/components/schemas/IntervalVariableSpec"}},"required":["kind","spec"],"type":"object"},"IntervalVariableSpec":{"additionalProperties":false,"description":"Interval variable specification","properties":{"auto":{"default":false,"type":"boolean"},"auto_count":{"default":0,"type":"integer"},"auto_min":{"default":"","type":"string"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","options","auto","auto_min","auto_count","refresh","hide","skipUrlSync"],"type":"object"},"LibraryPanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"LibraryPanel","type":"string"},"spec":{"$ref":"#/components/schemas/LibraryPanelKindSpec"}},"required":["kind","spec"],"type":"object"},"LibraryPanelKindSpec":{"additionalProperties":false,"properties":{"id":{"description":"Panel ID for the library panel in the dashboard","type":"number"},"libraryPanel":{"$ref":"#/components/schemas/LibraryPanelRef"},"title":{"description":"Title for the library panel in the dashboard","type":"string"}},"required":["id","title","libraryPanel"],"type":"object"},"LibraryPanelRef":{"additionalProperties":false,"description":"A library panel is a reusable panel that you can use in any dashboard.\nWhen you make a change to a library panel, that change propagates to all instances of where the panel is used.\nLibrary panels streamline reuse of panels across multiple dashboards.","properties":{"name":{"description":"Library panel name","type":"string"},"uid":{"description":"Library panel uid","type":"string"}},"required":["name","uid"],"type":"object"},"MappingType":{"description":"Supported value mapping types\n` + "`" + `value` + "`" + `: Maps text values to a color or different display text and color. For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.\n` + "`" + `range` + "`" + `: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.\n` + "`" + `regex` + "`" + `: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.\n` + "`" + `special` + "`" + `: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.","enum":["value","range","regex","special"],"type":"string"},"MatcherConfig":{"additionalProperties":false,"description":"Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.\nIt comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.","properties":{"id":{"default":"","description":"The matcher id. This is used to find the matcher implementation from registry.","type":"string"},"options":{"additionalProperties":{},"description":"The matcher options. This is specific to the matcher implementation.","type":"object"}},"required":["id"],"type":"object"},"MetricFindValue":{"additionalProperties":false,"description":"Define the MetricFindValue type","properties":{"expandable":{"type":"boolean"},"group":{"type":"string"},"text":{"type":"string"},"value":{"oneOf":[{"type":"string"},{"type":"number"}]}},"required":["text"],"type":"object"},"PanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"Panel","type":"string"},"spec":{"$ref":"#/components/schemas/PanelSpec"}},"required":["kind","spec"],"type":"object"},"PanelQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"PanelQuery","type":"string"},"spec":{"$ref":"#/components/schemas/PanelQuerySpec"}},"required":["kind","spec"],"type":"object"},"PanelQuerySpec":{"additionalProperties":false,"properties":{"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"hidden":{"type":"boolean"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refId":{"type":"string"}},"required":["query","refId","hidden"],"type":"object"},"PanelSpec":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QueryGroupKind"},"description":{"type":"string"},"id":{"type":"number"},"links":{"items":{"$ref":"#/components/schemas/DataLink"},"type":"array"},"title":{"type":"string"},"transparent":{"type":"boolean"},"vizConfig":{"$ref":"#/components/schemas/VizConfigKind"}},"required":["id","title","description","links","data","vizConfig"],"type":"object"},"QueryGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"QueryGroup","type":"string"},"spec":{"$ref":"#/components/schemas/QueryGroupSpec"}},"required":["kind","spec"],"type":"object"},"QueryGroupSpec":{"additionalProperties":false,"properties":{"queries":{"items":{"$ref":"#/components/schemas/PanelQueryKind"},"type":"array"},"queryOptions":{"$ref":"#/components/schemas/QueryOptionsSpec"},"transformations":{"items":{"$ref":"#/components/schemas/TransformationKind"},"type":"array"}},"required":["queries","transformations","queryOptions"],"type":"object"},"QueryOptionsSpec":{"additionalProperties":false,"properties":{"cacheTimeout":{"type":"string"},"hideTimeOverride":{"type":"boolean"},"interval":{"type":"string"},"maxDataPoints":{"type":"integer"},"queryCachingTTL":{"type":"integer"},"timeFrom":{"type":"string"},"timeShift":{"type":"string"}},"type":"object"},"QueryVariableKind":{"additionalProperties":false,"description":"Query variable kind","properties":{"kind":{"const":"QueryVariable","type":"string"},"spec":{"$ref":"#/components/schemas/QueryVariableSpec"}},"required":["kind","spec"],"type":"object"},"QueryVariableSpec":{"additionalProperties":false,"description":"Query variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"definition":{"type":"string"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"placeholder":{"type":"string"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"},"sort":{"$ref":"#/components/schemas/VariableSort"},"staticOptions":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"staticOptionsOrder":{"enum":["before","after","sorted"],"type":"string"}},"required":["name","current","hide","refresh","skipUrlSync","query","regex","sort","options","multi","includeAll","allowCustomValue"],"type":"object"},"RangeMap":{"additionalProperties":false,"description":"Maps numerical ranges to a display text and color.\nFor example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.","properties":{"options":{"additionalProperties":false,"description":"Range to match against and the result to apply when the value is within the range","properties":{"from":{"description":"Min value of the range. It can be null which means -Infinity","type":"number"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value is within the range"},"to":{"description":"Max value of the range. It can be null which means +Infinity","type":"number"}},"required":["from","to","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RegexMap":{"additionalProperties":false,"description":"Maps regular expressions to replacement text and a color.\nFor example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.","properties":{"options":{"additionalProperties":false,"description":"Regular expression to match against and the result to apply when the value matches the regex","properties":{"pattern":{"description":"Regular expression to match against","type":"string"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the regex"}},"required":["pattern","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RepeatMode":{"const":"variable","description":"other repeat modes will be added in the future: label, frame","type":"string"},"RepeatOptions":{"additionalProperties":false,"properties":{"direction":{"enum":["h","v"],"type":"string"},"maxPerRow":{"type":"integer"},"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayoutRow","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutRowSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowSpec":{"additionalProperties":false,"properties":{"collapse":{"type":"boolean"},"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"fillScreen":{"type":"boolean"},"hideHeader":{"type":"boolean"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/RowRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"RowsLayoutSpec":{"additionalProperties":false,"properties":{"rows":{"items":{"$ref":"#/components/schemas/RowsLayoutRowKind"},"type":"array"}},"required":["rows"],"type":"object"},"SpecialValueMap":{"additionalProperties":false,"description":"Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color.\nSee SpecialValueMatch to see the list of special values.\nFor example, you can configure a special value mapping so that null values appear as N/A.","properties":{"options":{"additionalProperties":false,"properties":{"match":{"$ref":"#/components/schemas/SpecialValueMatch","description":"Special value to match against"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the special value"}},"required":["match","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"SpecialValueMatch":{"description":"Special value types supported by the ` + "`" + `SpecialValueMap` + "`" + `","enum":["true","false","null","nan","null+nan","empty"],"type":"string"},"SwitchVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"SwitchVariable","type":"string"},"spec":{"$ref":"#/components/schemas/SwitchVariableSpec"}},"required":["kind","spec"],"type":"object"},"SwitchVariableSpec":{"additionalProperties":false,"description":"Switch variable specification","properties":{"current":{"default":"false","type":"string"},"description":{"type":"string"},"disabledValue":{"default":"false","type":"string"},"enabledValue":{"default":"true","type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","enabledValue","disabledValue","hide","skipUrlSync"],"type":"object"},"TabRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"TabsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutSpec":{"additionalProperties":false,"properties":{"tabs":{"items":{"$ref":"#/components/schemas/TabsLayoutTabKind"},"type":"array"}},"required":["tabs"],"type":"object"},"TabsLayoutTabKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayoutTab","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutTabSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutTabSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/TabRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"TextVariableKind":{"additionalProperties":false,"description":"Text variable kind","properties":{"kind":{"const":"TextVariable","type":"string"},"spec":{"$ref":"#/components/schemas/TextVariableSpec"}},"required":["kind","spec"],"type":"object"},"TextVariableSpec":{"additionalProperties":false,"description":"Text variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","query","hide","skipUrlSync"],"type":"object"},"Threshold":{"additionalProperties":false,"properties":{"color":{"type":"string"},"value":{"description":"Value null means -Infinity","type":"number"}},"required":["value","color"],"type":"object"},"ThresholdsConfig":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/ThresholdsMode"},"steps":{"items":{"$ref":"#/components/schemas/Threshold"},"type":"array"}},"required":["mode","steps"],"type":"object"},"ThresholdsMode":{"enum":["absolute","percentage"],"type":"string"},"TimeRangeOption":{"additionalProperties":false,"properties":{"display":{"default":"Last 6 hours","type":"string"},"from":{"default":"now-6h","type":"string"},"to":{"default":"now","type":"string"}},"required":["display","from","to"],"type":"object"},"TimeSettingsSpec":{"additionalProperties":false,"description":"Time configuration\nIt defines the default time config for the time picker, the refresh picker for the specific dashboard.","properties":{"autoRefresh":{"default":"","description":"Refresh rate of dashboard. Represented via interval string, e.g. \"5s\", \"1m\", \"1h\", \"1d\".\nv1: refresh","type":"string"},"autoRefreshIntervals":{"default":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"description":"Interval options available in the refresh picker dropdown.\nv1: timepicker.refresh_intervals","items":{"type":"string"},"type":"array"},"fiscalYearStartMonth":{"default":0,"description":"The month that the fiscal year starts on. 0 = January, 11 = December","type":"integer"},"from":{"default":"now-6h","description":"Start time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"hideTimepicker":{"default":false,"description":"Whether timepicker is visible or not.\nv1: timepicker.hidden","type":"boolean"},"nowDelay":{"description":"Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values.\nv1: timepicker.nowDelay","type":"string"},"quickRanges":{"description":"Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.\nv1: timepicker.quick_ranges , not exposed in the UI","items":{"$ref":"#/components/schemas/TimeRangeOption"},"type":"array"},"timezone":{"default":"browser","description":"Timezone of dashboard. Accepted values are IANA TZDB zone ID or \"browser\" or \"utc\".","type":"string"},"to":{"default":"now","description":"End time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"weekStart":{"description":"Day when the week starts. Expressed by the name of the day in lowercase, e.g. \"monday\".","enum":["saturday","monday","sunday"],"type":"string"}},"required":["from","to","autoRefresh","autoRefreshIntervals","hideTimepicker","fiscalYearStartMonth"],"type":"object"},"TransformationKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a TransformationKind is the transformation ID","type":"string"},"spec":{"$ref":"#/components/schemas/DataTransformerConfig"}},"required":["kind","spec"],"type":"object"},"ValueMap":{"additionalProperties":false,"description":"Maps text values to a color or different display text and color.\nFor example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.","properties":{"options":{"additionalProperties":{"$ref":"#/components/schemas/ValueMappingResult"},"description":"Map with \u003cvalue_to_match\u003e: ValueMappingResult. For example: { \"10\": { text: \"Perfection!\", color: \"green\" } }","type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"ValueMapping":{"oneOf":[{"$ref":"#/components/schemas/ValueMap"},{"$ref":"#/components/schemas/RangeMap"},{"$ref":"#/components/schemas/RegexMap"},{"$ref":"#/components/schemas/SpecialValueMap"}]},"ValueMappingResult":{"additionalProperties":false,"description":"Result used as replacement with text and color when the value matches","properties":{"color":{"description":"Text to use when the value matches","type":"string"},"icon":{"description":"Icon to display when the value matches. Only specific visualizations.","type":"string"},"index":{"description":"Position in the mapping array. Only used internally.","type":"integer"},"text":{"description":"Text to display when the value matches","type":"string"}},"type":"object"},"VariableHide":{"description":"Determine if the variable shows on dashboard\nAccepted values are ` + "`" + `dontHide` + "`" + ` (show label and value), ` + "`" + `hideLabel` + "`" + ` (show value only), ` + "`" + `hideVariable` + "`" + ` (show nothing).","enum":["dontHide","hideLabel","hideVariable"],"type":"string"},"VariableKind":{"oneOf":[{"$ref":"#/components/schemas/QueryVariableKind"},{"$ref":"#/components/schemas/TextVariableKind"},{"$ref":"#/components/schemas/ConstantVariableKind"},{"$ref":"#/components/schemas/DatasourceVariableKind"},{"$ref":"#/components/schemas/IntervalVariableKind"},{"$ref":"#/components/schemas/CustomVariableKind"},{"$ref":"#/components/schemas/GroupByVariableKind"},{"$ref":"#/components/schemas/AdhocVariableKind"},{"$ref":"#/components/schemas/SwitchVariableKind"}]},"VariableOption":{"additionalProperties":false,"description":"Variable option specification","properties":{"selected":{"description":"Whether the option is selected or not","type":"boolean"},"text":{"description":"Text to be displayed for the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]},"value":{"description":"Value of the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]}},"required":["text","value"],"type":"object"},"VariableRefresh":{"description":"Options to config when to refresh a variable\n` + "`" + `never` + "`" + `: Never refresh the variable\n` + "`" + `onDashboardLoad` + "`" + `: Queries the data source every time the dashboard loads.\n` + "`" + `onTimeRangeChanged` + "`" + `: Queries the data source when the dashboard time range changes.","enum":["never","onDashboardLoad","onTimeRangeChanged"],"type":"string"},"VariableSort":{"description":"Sort variable options\nAccepted values are:\n` + "`" + `disabled` + "`" + `: No sorting\n` + "`" + `alphabeticalAsc` + "`" + `: Alphabetical ASC\n` + "`" + `alphabeticalDesc` + "`" + `: Alphabetical DESC\n` + "`" + `numericalAsc` + "`" + `: Numerical ASC\n` + "`" + `numericalDesc` + "`" + `: Numerical DESC\n` + "`" + `alphabeticalCaseInsensitiveAsc` + "`" + `: Alphabetical Case Insensitive ASC\n` + "`" + `alphabeticalCaseInsensitiveDesc` + "`" + `: Alphabetical Case Insensitive DESC\n` + "`" + `naturalAsc` + "`" + `: Natural ASC\n` + "`" + `naturalDesc` + "`" + `: Natural DESC\nVariableSort enum with default value","enum":["disabled","alphabeticalAsc","alphabeticalDesc","numericalAsc","numericalDesc","alphabeticalCaseInsensitiveAsc","alphabeticalCaseInsensitiveDesc","naturalAsc","naturalDesc"],"type":"string"},"VizConfigKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a VizConfigKind is the plugin ID","type":"string"},"spec":{"$ref":"#/components/schemas/VizConfigSpec"}},"required":["kind","spec"],"type":"object"},"VizConfigSpec":{"additionalProperties":false,"description":"--- Kinds ---","properties":{"fieldConfig":{"$ref":"#/components/schemas/FieldConfigSource"},"options":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"pluginVersion":{"type":"string"}},"required":["pluginVersion","options","fieldConfig"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"annotations":{"items":{"$ref":"#/components/schemas/AnnotationQueryKind"},"type":"array"},"cursorSync":{"$ref":"#/components/schemas/DashboardCursorSync","default":"Off","description":"Configuration of dashboard cursor sync behavior.\n\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip."},"description":{"description":"Description of dashboard.","type":"string"},"editable":{"default":true,"description":"Whether a dashboard is editable or not.","type":"boolean"},"elements":{"additionalProperties":{"$ref":"#/components/schemas/Element"},"type":"object"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"links":{"description":"Links with references to other dashboards or external websites.","items":{"$ref":"#/components/schemas/DashboardLink"},"type":"array"},"liveNow":{"description":"When set to true, the dashboard will redraw panels at an interval matching the pixel width.\nThis will keep data \"moving left\" regardless of the query refresh rate. This setting helps\navoid dashboards presenting stale live data.","type":"boolean"},"preload":{"default":false,"description":"When set to true, the dashboard will load all panels in the dashboard when it's loaded.","type":"boolean"},"revision":{"description":"Plugins only. The version of the dashboard installed together with the plugin.\nThis is used to determine if the dashboard should be updated when the plugin is updated.","type":"integer"},"tags":{"description":"Tags associated with dashboard.","items":{"type":"string"},"type":"array"},"timeSettings":{"$ref":"#/components/schemas/TimeSettingsSpec"},"title":{"description":"Title of dashboard.","type":"string"},"variables":{"description":"Configured template variables.","items":{"$ref":"#/components/schemas/VariableKind"},"type":"array"}},"required":["annotations","cursorSync","elements","layout","links","preload","tags","timeSettings","title","variables"],"type":"object"},"status":{"additionalProperties":false,"properties":{"conversion":{"$ref":"#/components/schemas/ConversionStatus","description":"Optional conversion status."}},"type":"object"}}`) + rawSchemaDashboardv2alpha1 = []byte(`{"Action":{"additionalProperties":false,"properties":{"confirmation":{"type":"string"},"fetch":{"$ref":"#/components/schemas/FetchOptions"},"infinity":{"$ref":"#/components/schemas/InfinityOptions"},"oneClick":{"type":"boolean"},"style":{"additionalProperties":false,"properties":{"backgroundColor":{"type":"string"}},"type":"object"},"title":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionType"},"variables":{"items":{"$ref":"#/components/schemas/ActionVariable"},"type":"array"}},"required":["type","title"],"type":"object"},"ActionType":{"enum":["fetch","infinity"],"type":"string"},"ActionVariable":{"additionalProperties":false,"properties":{"key":{"type":"string"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionVariableType"}},"required":["key","name","type"],"type":"object"},"ActionVariableType":{"const":"string","description":"Action variable type","type":"string"},"AdHocFilterWithLabels":{"additionalProperties":false,"description":"Define the AdHocFilterWithLabels type","properties":{"condition":{"description":"@deprecated","type":"string"},"forceEdit":{"type":"boolean"},"key":{"type":"string"},"keyLabel":{"type":"string"},"operator":{"type":"string"},"origin":{"$ref":"#/components/schemas/FilterOrigin"},"value":{"type":"string"},"valueLabels":{"items":{"type":"string"},"type":"array"},"values":{"items":{"type":"string"},"type":"array"}},"required":["key","operator","value"],"type":"object"},"AdhocVariableKind":{"additionalProperties":false,"description":"Adhoc variable kind","properties":{"kind":{"const":"AdhocVariable","type":"string"},"spec":{"$ref":"#/components/schemas/AdhocVariableSpec"}},"required":["kind","spec"],"type":"object"},"AdhocVariableSpec":{"additionalProperties":false,"description":"Adhoc variable specification","properties":{"allowCustomValue":{"default":true,"type":"boolean"},"baseFilters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"defaultKeys":{"items":{"$ref":"#/components/schemas/MetricFindValue"},"type":"array"},"description":{"type":"string"},"filters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","baseFilters","filters","defaultKeys","hide","skipUrlSync","allowCustomValue"],"type":"object"},"AnnotationEventFieldMapping":{"additionalProperties":false,"description":"Annotation event field mapping. Defines how to map a data frame field to an annotation event field.","properties":{"regex":{"description":"Regular expression to apply to the field value","type":"string"},"source":{"default":"field","description":"Source type for the field value","type":"string"},"value":{"description":"Constant value to use when source is \"text\"","type":"string"}},"type":"object"},"AnnotationPanelFilter":{"additionalProperties":false,"properties":{"exclude":{"default":false,"description":"Should the specified panels be included or excluded","type":"boolean"},"ids":{"description":"Panel IDs that should be included or excluded","items":{"type":"integer"},"type":"array"}},"required":["ids"],"type":"object"},"AnnotationQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"AnnotationQuery","type":"string"},"spec":{"$ref":"#/components/schemas/AnnotationQuerySpec"}},"required":["kind","spec"],"type":"object"},"AnnotationQuerySpec":{"additionalProperties":false,"properties":{"builtIn":{"default":false,"type":"boolean"},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"enable":{"type":"boolean"},"filter":{"$ref":"#/components/schemas/AnnotationPanelFilter"},"hide":{"type":"boolean"},"iconColor":{"type":"string"},"legacyOptions":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"Catch-all field for datasource-specific properties","type":"object"},"mappings":{"additionalProperties":{"$ref":"#/components/schemas/AnnotationEventFieldMapping"},"description":"Mappings define how to convert data frame fields to annotation event fields.","type":"object"},"name":{"type":"string"},"query":{"$ref":"#/components/schemas/DataQueryKind"}},"required":["enable","hide","iconColor","name"],"type":"object"},"AutoGridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutItemSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"element":{"$ref":"#/components/schemas/ElementReference"},"repeat":{"$ref":"#/components/schemas/AutoGridRepeatOptions"}},"required":["element"],"type":"object"},"AutoGridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutSpec":{"additionalProperties":false,"properties":{"columnWidth":{"type":"number"},"columnWidthMode":{"default":"standard","enum":["narrow","standard","wide","custom"],"type":"string"},"fillScreen":{"default":false,"type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/AutoGridLayoutItemKind"},"type":"array"},"maxColumnCount":{"default":3,"type":"number"},"rowHeight":{"type":"number"},"rowHeightMode":{"default":"standard","enum":["short","standard","tall","custom"],"type":"string"}},"required":["columnWidthMode","rowHeightMode","items"],"type":"object"},"AutoGridRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"ConditionalRenderingDataKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingData","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingDataSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingDataSpec":{"additionalProperties":false,"properties":{"value":{"type":"boolean"}},"required":["value"],"type":"object"},"ConditionalRenderingGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingGroup","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingGroupSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingGroupSpec":{"additionalProperties":false,"properties":{"condition":{"enum":["and","or"],"type":"string"},"items":{"items":{"oneOf":[{"$ref":"#/components/schemas/ConditionalRenderingVariableKind"},{"$ref":"#/components/schemas/ConditionalRenderingDataKind"},{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeKind"}]},"type":"array"},"visibility":{"enum":["show","hide"],"type":"string"}},"required":["visibility","condition","items"],"type":"object"},"ConditionalRenderingTimeRangeSizeKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingTimeRangeSize","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingTimeRangeSizeSpec":{"additionalProperties":false,"properties":{"value":{"type":"string"}},"required":["value"],"type":"object"},"ConditionalRenderingVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingVariableSpec":{"additionalProperties":false,"properties":{"operator":{"enum":["equals","notEquals","matches","notMatches"],"type":"string"},"value":{"type":"string"},"variable":{"type":"string"}},"required":["variable","operator","value"],"type":"object"},"ConstantVariableKind":{"additionalProperties":false,"description":"Constant variable kind","properties":{"kind":{"const":"ConstantVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConstantVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConstantVariableSpec":{"additionalProperties":false,"description":"Constant variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","hide","skipUrlSync"],"type":"object"},"ConversionStatus":{"additionalProperties":false,"description":"ConversionStatus is the status of the conversion of the dashboard.","properties":{"error":{"description":"The error message from the conversion.\nEmpty if the conversion has not failed.","type":"string"},"failed":{"description":"Whether from another version has failed.\nIf true, means that the dashboard is not valid,\nand the caller should instead fetch the stored version.","type":"boolean"},"source":{"additionalProperties":{},"description":"The original value map[string]any","type":"object"},"storedVersion":{"description":"The version which was stored when the dashboard was created / updated.\nFetching this version should always succeed.","type":"string"}},"required":["failed"],"type":"object"},"CustomVariableKind":{"additionalProperties":false,"description":"Custom variable kind","properties":{"kind":{"const":"CustomVariable","type":"string"},"spec":{"$ref":"#/components/schemas/CustomVariableSpec"}},"required":["kind","spec"],"type":"object"},"CustomVariableSpec":{"additionalProperties":false,"description":"Custom variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"},"valuesFormat":{"enum":["csv","json"],"type":"string"}},"required":["name","query","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"Dashboard":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"DashboardCursorSync":{"description":"\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip.","enum":["Crosshair","Tooltip","Off"],"type":"string"},"DashboardLink":{"additionalProperties":false,"description":"Links with references to other dashboards or external resources","properties":{"asDropdown":{"default":false,"description":"If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards","type":"boolean"},"icon":{"description":"Icon name to be displayed with the link","type":"string"},"includeVars":{"default":false,"description":"If true, includes current template variables values in the link as query params","type":"boolean"},"keepTime":{"default":false,"description":"If true, includes current time range in the link as query params","type":"boolean"},"placement":{"$ref":"#/components/schemas/DashboardLinkPlacement","description":"Placement can be used to display the link somewhere else on the dashboard other than above the visualisations."},"tags":{"description":"List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards","items":{"type":"string"},"type":"array"},"targetBlank":{"default":false,"description":"If true, the link will be opened in a new tab","type":"boolean"},"title":{"description":"Title to display with the link","type":"string"},"tooltip":{"description":"Tooltip to display when the user hovers their mouse over it","type":"string"},"type":{"$ref":"#/components/schemas/DashboardLinkType","description":"Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)\nFIXME: The type is generated as ` + "`" + `type: DashboardLinkType | dashboardLinkType.Link;` + "`" + ` but it should be ` + "`" + `type: DashboardLinkType` + "`" + `"},"url":{"description":"Link URL. Only required/valid if the type is link","type":"string"}},"required":["title","type","icon","tooltip","tags","asDropdown","targetBlank","includeVars","keepTime"],"type":"object"},"DashboardLinkPlacement":{"const":"inControlsMenu","description":"Dashboard Link placement. Defines where the link should be displayed.\n- \"inControlsMenu\" renders the link in bottom part of the dashboard controls dropdown menu","type":"string"},"DashboardLinkType":{"description":"Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)","enum":["link","dashboards"],"type":"string"},"DataLink":{"additionalProperties":false,"properties":{"targetBlank":{"type":"boolean"},"title":{"type":"string"},"url":{"type":"string"}},"required":["title","url"],"type":"object"},"DataQueryKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a DataQueryKind is the datasource type","type":"string"},"spec":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"}},"required":["kind","spec"],"type":"object"},"DataSourceRef":{"additionalProperties":false,"properties":{"type":{"description":"The plugin type-id","type":"string"},"uid":{"description":"Specific datasource instance","type":"string"}},"type":"object"},"DataTopic":{"description":"A topic is attached to DataFrame metadata in query results.\nThis specifies where the data should be used.","enum":["series","annotations","alertStates"],"type":"string"},"DataTransformerConfig":{"additionalProperties":false,"description":"Transformations allow to manipulate data returned by a query before the system applies a visualization.\nUsing transformations you can: rename fields, join time series data, perform mathematical operations across queries,\nuse the output of one transformation as the input to another transformation, etc.","properties":{"disabled":{"description":"Disabled transformations are skipped","type":"boolean"},"filter":{"$ref":"#/components/schemas/MatcherConfig","description":"Optional frame matcher. When missing it will be applied to all results"},"id":{"description":"Unique identifier of transformer","type":"string"},"options":{"additionalProperties":{},"description":"Options to be passed to the transformer\nValid options depend on the transformer id","type":"object"},"topic":{"$ref":"#/components/schemas/DataTopic","description":"Where to pull DataFrames from as input to transformation"}},"required":["id","options"],"type":"object"},"DatasourceVariableKind":{"additionalProperties":false,"description":"Datasource variable kind","properties":{"kind":{"const":"DatasourceVariable","type":"string"},"spec":{"$ref":"#/components/schemas/DatasourceVariableSpec"}},"required":["kind","spec"],"type":"object"},"DatasourceVariableSpec":{"additionalProperties":false,"description":"Datasource variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"pluginId":{"default":"","type":"string"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","pluginId","refresh","regex","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"DynamicConfigValue":{"additionalProperties":false,"properties":{"id":{"default":"","type":"string"},"value":{"additionalProperties":{},"type":"object"}},"required":["id"],"type":"object"},"Element":{"description":"Supported dashboard elements\n|* more element types in the future","oneOf":[{"$ref":"#/components/schemas/PanelKind"},{"$ref":"#/components/schemas/LibraryPanelKind"}]},"ElementReference":{"additionalProperties":false,"properties":{"kind":{"const":"ElementReference","type":"string"},"name":{"type":"string"}},"required":["kind","name"],"type":"object"},"FetchOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url"],"type":"object"},"FieldColor":{"additionalProperties":false,"description":"Map a field to a color.","properties":{"fixedColor":{"description":"The fixed color value for fixed or shades color modes.","type":"string"},"mode":{"$ref":"#/components/schemas/FieldColorModeId","description":"The main color scheme mode."},"seriesBy":{"$ref":"#/components/schemas/FieldColorSeriesByMode","description":"Some visualizations need to know how to assign a series color from by value color schemes."}},"required":["mode"],"type":"object"},"FieldColorModeId":{"description":"Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value.\nContinuous color interpolates a color using the percentage of a value relative to min and max.\nAccepted values are:\n` + "`" + `thresholds` + "`" + `: From thresholds. Informs Grafana to take the color from the matching threshold\n` + "`" + `palette-classic` + "`" + `: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `palette-classic-by-name` + "`" + `: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `continuous-viridis` + "`" + `: Continuous Viridis palette mode\n` + "`" + `continuous-magma` + "`" + `: Continuous Magma palette mode\n` + "`" + `continuous-plasma` + "`" + `: Continuous Plasma palette mode\n` + "`" + `continuous-inferno` + "`" + `: Continuous Inferno palette mode\n` + "`" + `continuous-cividis` + "`" + `: Continuous Cividis palette mode\n` + "`" + `continuous-GrYlRd` + "`" + `: Continuous Green-Yellow-Red palette mode\n` + "`" + `continuous-RdYlGr` + "`" + `: Continuous Red-Yellow-Green palette mode\n` + "`" + `continuous-BlYlRd` + "`" + `: Continuous Blue-Yellow-Red palette mode\n` + "`" + `continuous-YlRd` + "`" + `: Continuous Yellow-Red palette mode\n` + "`" + `continuous-BlPu` + "`" + `: Continuous Blue-Purple palette mode\n` + "`" + `continuous-YlBl` + "`" + `: Continuous Yellow-Blue palette mode\n` + "`" + `continuous-blues` + "`" + `: Continuous Blue palette mode\n` + "`" + `continuous-reds` + "`" + `: Continuous Red palette mode\n` + "`" + `continuous-greens` + "`" + `: Continuous Green palette mode\n` + "`" + `continuous-purples` + "`" + `: Continuous Purple palette mode\n` + "`" + `shades` + "`" + `: Shades of a single color. Specify a single color, useful in an override rule.\n` + "`" + `fixed` + "`" + `: Fixed color mode. Specify a single color, useful in an override rule.","enum":["thresholds","palette-classic","palette-classic-by-name","continuous-viridis","continuous-magma","continuous-plasma","continuous-inferno","continuous-cividis","continuous-GrYlRd","continuous-RdYlGr","continuous-BlYlRd","continuous-YlRd","continuous-BlPu","continuous-YlBl","continuous-blues","continuous-reds","continuous-greens","continuous-purples","fixed","shades"],"type":"string"},"FieldColorSeriesByMode":{"description":"Defines how to assign a series color from \"by value\" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value.","enum":["min","max","last"],"type":"string"},"FieldConfig":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"actions":{"description":"Define interactive HTTP requests that can be triggered from data visualizations.","items":{"$ref":"#/components/schemas/Action"},"type":"array"},"color":{"$ref":"#/components/schemas/FieldColor","description":"Panel color configuration"},"custom":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"custom is specified by the FieldConfig field\nin panel plugin schemas.","type":"object"},"decimals":{"description":"Specify the number of decimals Grafana includes in the rendered value.\nIf you leave this field blank, Grafana automatically truncates the number of decimals based on the value.\nFor example 1.1234 will display as 1.12 and 100.456 will display as 100.\nTo display all decimals, set the unit to ` + "`" + `String` + "`" + `.","type":"number"},"description":{"description":"Human readable field metadata","type":"string"},"displayName":{"description":"The display value for this field. This supports template variables blank is auto","type":"string"},"displayNameFromDS":{"description":"This can be used by data sources that return and explicit naming structure for values and labels\nWhen this property is configured, this value is used rather than the default naming strategy.","type":"string"},"filterable":{"description":"True if data source field supports ad-hoc filters","type":"boolean"},"links":{"description":"The behavior when clicking on a result","items":{"additionalProperties":{},"type":"object"},"type":"array"},"mappings":{"description":"Convert input values into a display string","items":{"$ref":"#/components/schemas/ValueMapping"},"type":"array"},"max":{"description":"The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"min":{"description":"The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"noValue":{"description":"Alternative to empty string","type":"string"},"path":{"description":"An explicit path to the field in the datasource. When the frame meta includes a path,\nThis will default to ` + "`" + `${frame.meta.path}/${field.name}\n\nWhen defined, this value can be used as an identifier within the datasource scope, and\nmay be used to update the results","type":"string"},"thresholds":{"$ref":"#/components/schemas/ThresholdsConfig","description":"Map numeric values to states"},"unit":{"description":"Unit a field should use. The unit you select is applied to all fields except time.\nYou can use the units ID availables in Grafana or a custom unit.\nAvailable units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts\nAs custom unit, you can use the following formats:\n` + "`" + `suffix:\u003csuffix\u003e` + "`" + ` for custom unit that should go after value.\n` + "`" + `prefix:\u003cprefix\u003e` + "`" + ` for custom unit that should go before value.\n` + "`" + `time:\u003cformat\u003e` + "`" + ` For custom date time formats type for example ` + "`" + `time:YYYY-MM-DD` + "`" + `.\n` + "`" + `si:\u003cbase scale\u003e\u003cunit characters\u003e` + "`" + ` for custom SI units. For example: ` + "`" + `si: mF` + "`" + `. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.\n` + "`" + `count:\u003cunit\u003e` + "`" + ` for a custom count unit.\n` + "`" + `currency:\u003cunit\u003e` + "`" + ` for custom a currency unit.","type":"string"},"writeable":{"description":"True if data source can write a value to the path. Auth/authz are supported separately","type":"boolean"}},"type":"object"},"FieldConfigSource":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"defaults":{"$ref":"#/components/schemas/FieldConfig","description":"Defaults are the options applied to all fields."},"overrides":{"description":"Overrides are the options applied to specific fields overriding the defaults.","items":{"additionalProperties":false,"properties":{"__systemRef":{"description":"Describes config override rules created when interacting with Grafana.","type":"string"},"matcher":{"$ref":"#/components/schemas/MatcherConfig"},"properties":{"items":{"$ref":"#/components/schemas/DynamicConfigValue"},"type":"array"}},"required":["matcher","properties"],"type":"object"},"type":"array"}},"required":["defaults","overrides"],"type":"object"},"FilterOrigin":{"const":"dashboard","description":"Determine the origin of the adhoc variable filter","type":"string"},"GridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutItemSpec":{"additionalProperties":false,"properties":{"element":{"$ref":"#/components/schemas/ElementReference","description":"reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference"},"height":{"type":"integer"},"repeat":{"$ref":"#/components/schemas/RepeatOptions"},"width":{"type":"integer"},"x":{"type":"integer"},"y":{"type":"integer"}},"required":["x","y","width","height","element"],"type":"object"},"GridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutSpec":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/GridLayoutItemKind"},"type":"array"}},"required":["items"],"type":"object"},"GroupByVariableKind":{"additionalProperties":false,"description":"Group variable kind","properties":{"kind":{"const":"GroupByVariable","type":"string"},"spec":{"$ref":"#/components/schemas/GroupByVariableSpec"}},"required":["kind","spec"],"type":"object"},"GroupByVariableSpec":{"additionalProperties":false,"description":"GroupBy variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"defaultValue":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","options","multi","hide","skipUrlSync"],"type":"object"},"HttpRequestMethod":{"enum":["GET","PUT","POST","DELETE","PATCH"],"type":"string"},"InfinityOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"datasourceUid":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url","datasourceUid"],"type":"object"},"IntervalVariableKind":{"additionalProperties":false,"description":"Interval variable kind","properties":{"kind":{"const":"IntervalVariable","type":"string"},"spec":{"$ref":"#/components/schemas/IntervalVariableSpec"}},"required":["kind","spec"],"type":"object"},"IntervalVariableSpec":{"additionalProperties":false,"description":"Interval variable specification","properties":{"auto":{"default":false,"type":"boolean"},"auto_count":{"default":0,"type":"integer"},"auto_min":{"default":"","type":"string"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","options","auto","auto_min","auto_count","refresh","hide","skipUrlSync"],"type":"object"},"LibraryPanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"LibraryPanel","type":"string"},"spec":{"$ref":"#/components/schemas/LibraryPanelKindSpec"}},"required":["kind","spec"],"type":"object"},"LibraryPanelKindSpec":{"additionalProperties":false,"properties":{"id":{"description":"Panel ID for the library panel in the dashboard","type":"number"},"libraryPanel":{"$ref":"#/components/schemas/LibraryPanelRef"},"title":{"description":"Title for the library panel in the dashboard","type":"string"}},"required":["id","title","libraryPanel"],"type":"object"},"LibraryPanelRef":{"additionalProperties":false,"description":"A library panel is a reusable panel that you can use in any dashboard.\nWhen you make a change to a library panel, that change propagates to all instances of where the panel is used.\nLibrary panels streamline reuse of panels across multiple dashboards.","properties":{"name":{"description":"Library panel name","type":"string"},"uid":{"description":"Library panel uid","type":"string"}},"required":["name","uid"],"type":"object"},"MappingType":{"description":"Supported value mapping types\n` + "`" + `value` + "`" + `: Maps text values to a color or different display text and color. For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.\n` + "`" + `range` + "`" + `: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.\n` + "`" + `regex` + "`" + `: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.\n` + "`" + `special` + "`" + `: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.","enum":["value","range","regex","special"],"type":"string"},"MatcherConfig":{"additionalProperties":false,"description":"Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.\nIt comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.","properties":{"id":{"default":"","description":"The matcher id. This is used to find the matcher implementation from registry.","type":"string"},"options":{"additionalProperties":{},"description":"The matcher options. This is specific to the matcher implementation.","type":"object"}},"required":["id"],"type":"object"},"MetricFindValue":{"additionalProperties":false,"description":"Define the MetricFindValue type","properties":{"expandable":{"type":"boolean"},"group":{"type":"string"},"text":{"type":"string"},"value":{"oneOf":[{"type":"string"},{"type":"number"}]}},"required":["text"],"type":"object"},"PanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"Panel","type":"string"},"spec":{"$ref":"#/components/schemas/PanelSpec"}},"required":["kind","spec"],"type":"object"},"PanelQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"PanelQuery","type":"string"},"spec":{"$ref":"#/components/schemas/PanelQuerySpec"}},"required":["kind","spec"],"type":"object"},"PanelQuerySpec":{"additionalProperties":false,"properties":{"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"hidden":{"type":"boolean"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refId":{"type":"string"}},"required":["query","refId","hidden"],"type":"object"},"PanelSpec":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QueryGroupKind"},"description":{"type":"string"},"id":{"type":"number"},"links":{"items":{"$ref":"#/components/schemas/DataLink"},"type":"array"},"title":{"type":"string"},"transparent":{"type":"boolean"},"vizConfig":{"$ref":"#/components/schemas/VizConfigKind"}},"required":["id","title","description","links","data","vizConfig"],"type":"object"},"QueryGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"QueryGroup","type":"string"},"spec":{"$ref":"#/components/schemas/QueryGroupSpec"}},"required":["kind","spec"],"type":"object"},"QueryGroupSpec":{"additionalProperties":false,"properties":{"queries":{"items":{"$ref":"#/components/schemas/PanelQueryKind"},"type":"array"},"queryOptions":{"$ref":"#/components/schemas/QueryOptionsSpec"},"transformations":{"items":{"$ref":"#/components/schemas/TransformationKind"},"type":"array"}},"required":["queries","transformations","queryOptions"],"type":"object"},"QueryOptionsSpec":{"additionalProperties":false,"properties":{"cacheTimeout":{"type":"string"},"hideTimeOverride":{"type":"boolean"},"interval":{"type":"string"},"maxDataPoints":{"type":"integer"},"queryCachingTTL":{"type":"integer"},"timeFrom":{"type":"string"},"timeShift":{"type":"string"}},"type":"object"},"QueryVariableKind":{"additionalProperties":false,"description":"Query variable kind","properties":{"kind":{"const":"QueryVariable","type":"string"},"spec":{"$ref":"#/components/schemas/QueryVariableSpec"}},"required":["kind","spec"],"type":"object"},"QueryVariableSpec":{"additionalProperties":false,"description":"Query variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"datasource":{"$ref":"#/components/schemas/DataSourceRef"},"definition":{"type":"string"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"placeholder":{"type":"string"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"regexApplyTo":{"$ref":"#/components/schemas/VariableRegexApplyTo","default":"value"},"skipUrlSync":{"default":false,"type":"boolean"},"sort":{"$ref":"#/components/schemas/VariableSort"},"staticOptions":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"staticOptionsOrder":{"enum":["before","after","sorted"],"type":"string"}},"required":["name","current","hide","refresh","skipUrlSync","query","regex","sort","options","multi","includeAll","allowCustomValue"],"type":"object"},"RangeMap":{"additionalProperties":false,"description":"Maps numerical ranges to a display text and color.\nFor example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.","properties":{"options":{"additionalProperties":false,"description":"Range to match against and the result to apply when the value is within the range","properties":{"from":{"description":"Min value of the range. It can be null which means -Infinity","type":"number"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value is within the range"},"to":{"description":"Max value of the range. It can be null which means +Infinity","type":"number"}},"required":["from","to","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RegexMap":{"additionalProperties":false,"description":"Maps regular expressions to replacement text and a color.\nFor example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.","properties":{"options":{"additionalProperties":false,"description":"Regular expression to match against and the result to apply when the value matches the regex","properties":{"pattern":{"description":"Regular expression to match against","type":"string"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the regex"}},"required":["pattern","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RepeatMode":{"const":"variable","description":"other repeat modes will be added in the future: label, frame","type":"string"},"RepeatOptions":{"additionalProperties":false,"properties":{"direction":{"enum":["h","v"],"type":"string"},"maxPerRow":{"type":"integer"},"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayoutRow","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutRowSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowSpec":{"additionalProperties":false,"properties":{"collapse":{"type":"boolean"},"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"fillScreen":{"type":"boolean"},"hideHeader":{"type":"boolean"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/RowRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"RowsLayoutSpec":{"additionalProperties":false,"properties":{"rows":{"items":{"$ref":"#/components/schemas/RowsLayoutRowKind"},"type":"array"}},"required":["rows"],"type":"object"},"SpecialValueMap":{"additionalProperties":false,"description":"Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color.\nSee SpecialValueMatch to see the list of special values.\nFor example, you can configure a special value mapping so that null values appear as N/A.","properties":{"options":{"additionalProperties":false,"properties":{"match":{"$ref":"#/components/schemas/SpecialValueMatch","description":"Special value to match against"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the special value"}},"required":["match","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"SpecialValueMatch":{"description":"Special value types supported by the ` + "`" + `SpecialValueMap` + "`" + `","enum":["true","false","null","nan","null+nan","empty"],"type":"string"},"SwitchVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"SwitchVariable","type":"string"},"spec":{"$ref":"#/components/schemas/SwitchVariableSpec"}},"required":["kind","spec"],"type":"object"},"SwitchVariableSpec":{"additionalProperties":false,"description":"Switch variable specification","properties":{"current":{"default":"false","type":"string"},"description":{"type":"string"},"disabledValue":{"default":"false","type":"string"},"enabledValue":{"default":"true","type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","enabledValue","disabledValue","hide","skipUrlSync"],"type":"object"},"TabRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"TabsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutSpec":{"additionalProperties":false,"properties":{"tabs":{"items":{"$ref":"#/components/schemas/TabsLayoutTabKind"},"type":"array"}},"required":["tabs"],"type":"object"},"TabsLayoutTabKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayoutTab","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutTabSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutTabSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/TabRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"TextVariableKind":{"additionalProperties":false,"description":"Text variable kind","properties":{"kind":{"const":"TextVariable","type":"string"},"spec":{"$ref":"#/components/schemas/TextVariableSpec"}},"required":["kind","spec"],"type":"object"},"TextVariableSpec":{"additionalProperties":false,"description":"Text variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","query","hide","skipUrlSync"],"type":"object"},"Threshold":{"additionalProperties":false,"properties":{"color":{"type":"string"},"value":{"description":"Value null means -Infinity","type":"number"}},"required":["value","color"],"type":"object"},"ThresholdsConfig":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/ThresholdsMode"},"steps":{"items":{"$ref":"#/components/schemas/Threshold"},"type":"array"}},"required":["mode","steps"],"type":"object"},"ThresholdsMode":{"enum":["absolute","percentage"],"type":"string"},"TimeRangeOption":{"additionalProperties":false,"properties":{"display":{"default":"Last 6 hours","type":"string"},"from":{"default":"now-6h","type":"string"},"to":{"default":"now","type":"string"}},"required":["display","from","to"],"type":"object"},"TimeSettingsSpec":{"additionalProperties":false,"description":"Time configuration\nIt defines the default time config for the time picker, the refresh picker for the specific dashboard.","properties":{"autoRefresh":{"default":"","description":"Refresh rate of dashboard. Represented via interval string, e.g. \"5s\", \"1m\", \"1h\", \"1d\".\nv1: refresh","type":"string"},"autoRefreshIntervals":{"default":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"description":"Interval options available in the refresh picker dropdown.\nv1: timepicker.refresh_intervals","items":{"type":"string"},"type":"array"},"fiscalYearStartMonth":{"default":0,"description":"The month that the fiscal year starts on. 0 = January, 11 = December","type":"integer"},"from":{"default":"now-6h","description":"Start time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"hideTimepicker":{"default":false,"description":"Whether timepicker is visible or not.\nv1: timepicker.hidden","type":"boolean"},"nowDelay":{"description":"Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values.\nv1: timepicker.nowDelay","type":"string"},"quickRanges":{"description":"Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.\nv1: timepicker.quick_ranges , not exposed in the UI","items":{"$ref":"#/components/schemas/TimeRangeOption"},"type":"array"},"timezone":{"default":"browser","description":"Timezone of dashboard. Accepted values are IANA TZDB zone ID or \"browser\" or \"utc\".","type":"string"},"to":{"default":"now","description":"End time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"weekStart":{"description":"Day when the week starts. Expressed by the name of the day in lowercase, e.g. \"monday\".","enum":["saturday","monday","sunday"],"type":"string"}},"required":["from","to","autoRefresh","autoRefreshIntervals","hideTimepicker","fiscalYearStartMonth"],"type":"object"},"TransformationKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a TransformationKind is the transformation ID","type":"string"},"spec":{"$ref":"#/components/schemas/DataTransformerConfig"}},"required":["kind","spec"],"type":"object"},"ValueMap":{"additionalProperties":false,"description":"Maps text values to a color or different display text and color.\nFor example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.","properties":{"options":{"additionalProperties":{"$ref":"#/components/schemas/ValueMappingResult"},"description":"Map with \u003cvalue_to_match\u003e: ValueMappingResult. For example: { \"10\": { text: \"Perfection!\", color: \"green\" } }","type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"ValueMapping":{"oneOf":[{"$ref":"#/components/schemas/ValueMap"},{"$ref":"#/components/schemas/RangeMap"},{"$ref":"#/components/schemas/RegexMap"},{"$ref":"#/components/schemas/SpecialValueMap"}]},"ValueMappingResult":{"additionalProperties":false,"description":"Result used as replacement with text and color when the value matches","properties":{"color":{"description":"Text to use when the value matches","type":"string"},"icon":{"description":"Icon to display when the value matches. Only specific visualizations.","type":"string"},"index":{"description":"Position in the mapping array. Only used internally.","type":"integer"},"text":{"description":"Text to display when the value matches","type":"string"}},"type":"object"},"VariableHide":{"description":"Determine if the variable shows on dashboard\nAccepted values are ` + "`" + `dontHide` + "`" + ` (show label and value), ` + "`" + `hideLabel` + "`" + ` (show value only), ` + "`" + `hideVariable` + "`" + ` (show nothing).","enum":["dontHide","hideLabel","hideVariable"],"type":"string"},"VariableKind":{"oneOf":[{"$ref":"#/components/schemas/QueryVariableKind"},{"$ref":"#/components/schemas/TextVariableKind"},{"$ref":"#/components/schemas/ConstantVariableKind"},{"$ref":"#/components/schemas/DatasourceVariableKind"},{"$ref":"#/components/schemas/IntervalVariableKind"},{"$ref":"#/components/schemas/CustomVariableKind"},{"$ref":"#/components/schemas/GroupByVariableKind"},{"$ref":"#/components/schemas/AdhocVariableKind"},{"$ref":"#/components/schemas/SwitchVariableKind"}]},"VariableOption":{"additionalProperties":false,"description":"Variable option specification","properties":{"selected":{"description":"Whether the option is selected or not","type":"boolean"},"text":{"description":"Text to be displayed for the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]},"value":{"description":"Value of the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]}},"required":["text","value"],"type":"object"},"VariableRefresh":{"description":"Options to config when to refresh a variable\n` + "`" + `never` + "`" + `: Never refresh the variable\n` + "`" + `onDashboardLoad` + "`" + `: Queries the data source every time the dashboard loads.\n` + "`" + `onTimeRangeChanged` + "`" + `: Queries the data source when the dashboard time range changes.","enum":["never","onDashboardLoad","onTimeRangeChanged"],"type":"string"},"VariableRegexApplyTo":{"description":"Determine whether regex applies to variable value or display text\nAccepted values are ` + "`" + `value` + "`" + ` (apply to value used in queries) or ` + "`" + `text` + "`" + ` (apply to display text shown to users)","enum":["value","text"],"type":"string"},"VariableSort":{"description":"Sort variable options\nAccepted values are:\n` + "`" + `disabled` + "`" + `: No sorting\n` + "`" + `alphabeticalAsc` + "`" + `: Alphabetical ASC\n` + "`" + `alphabeticalDesc` + "`" + `: Alphabetical DESC\n` + "`" + `numericalAsc` + "`" + `: Numerical ASC\n` + "`" + `numericalDesc` + "`" + `: Numerical DESC\n` + "`" + `alphabeticalCaseInsensitiveAsc` + "`" + `: Alphabetical Case Insensitive ASC\n` + "`" + `alphabeticalCaseInsensitiveDesc` + "`" + `: Alphabetical Case Insensitive DESC\n` + "`" + `naturalAsc` + "`" + `: Natural ASC\n` + "`" + `naturalDesc` + "`" + `: Natural DESC\nVariableSort enum with default value","enum":["disabled","alphabeticalAsc","alphabeticalDesc","numericalAsc","numericalDesc","alphabeticalCaseInsensitiveAsc","alphabeticalCaseInsensitiveDesc","naturalAsc","naturalDesc"],"type":"string"},"VizConfigKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a VizConfigKind is the plugin ID","type":"string"},"spec":{"$ref":"#/components/schemas/VizConfigSpec"}},"required":["kind","spec"],"type":"object"},"VizConfigSpec":{"additionalProperties":false,"description":"--- Kinds ---","properties":{"fieldConfig":{"$ref":"#/components/schemas/FieldConfigSource"},"options":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"pluginVersion":{"type":"string"}},"required":["pluginVersion","options","fieldConfig"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"annotations":{"items":{"$ref":"#/components/schemas/AnnotationQueryKind"},"type":"array"},"cursorSync":{"$ref":"#/components/schemas/DashboardCursorSync","default":"Off","description":"Configuration of dashboard cursor sync behavior.\n\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip."},"description":{"description":"Description of dashboard.","type":"string"},"editable":{"default":true,"description":"Whether a dashboard is editable or not.","type":"boolean"},"elements":{"additionalProperties":{"$ref":"#/components/schemas/Element"},"type":"object"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"links":{"description":"Links with references to other dashboards or external websites.","items":{"$ref":"#/components/schemas/DashboardLink"},"type":"array"},"liveNow":{"description":"When set to true, the dashboard will redraw panels at an interval matching the pixel width.\nThis will keep data \"moving left\" regardless of the query refresh rate. This setting helps\navoid dashboards presenting stale live data.","type":"boolean"},"preload":{"default":false,"description":"When set to true, the dashboard will load all panels in the dashboard when it's loaded.","type":"boolean"},"revision":{"description":"Plugins only. The version of the dashboard installed together with the plugin.\nThis is used to determine if the dashboard should be updated when the plugin is updated.","type":"integer"},"tags":{"description":"Tags associated with dashboard.","items":{"type":"string"},"type":"array"},"timeSettings":{"$ref":"#/components/schemas/TimeSettingsSpec"},"title":{"description":"Title of dashboard.","type":"string"},"variables":{"description":"Configured template variables.","items":{"$ref":"#/components/schemas/VariableKind"},"type":"array"}},"required":["annotations","cursorSync","elements","layout","links","preload","tags","timeSettings","title","variables"],"type":"object"},"status":{"additionalProperties":false,"properties":{"conversion":{"$ref":"#/components/schemas/ConversionStatus","description":"Optional conversion status."}},"type":"object"}}`) versionSchemaDashboardv2alpha1 app.VersionSchema _ = json.Unmarshal(rawSchemaDashboardv2alpha1, &versionSchemaDashboardv2alpha1) - rawSchemaDashboardv2beta1 = []byte(`{"Action":{"additionalProperties":false,"properties":{"confirmation":{"type":"string"},"fetch":{"$ref":"#/components/schemas/FetchOptions"},"infinity":{"$ref":"#/components/schemas/InfinityOptions"},"oneClick":{"type":"boolean"},"style":{"additionalProperties":false,"properties":{"backgroundColor":{"type":"string"}},"type":"object"},"title":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionType"},"variables":{"items":{"$ref":"#/components/schemas/ActionVariable"},"type":"array"}},"required":["type","title"],"type":"object"},"ActionType":{"enum":["fetch","infinity"],"type":"string"},"ActionVariable":{"additionalProperties":false,"properties":{"key":{"type":"string"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionVariableType"}},"required":["key","name","type"],"type":"object"},"ActionVariableType":{"const":"string","description":"Action variable type","type":"string"},"AdHocFilterWithLabels":{"additionalProperties":false,"description":"Define the AdHocFilterWithLabels type","properties":{"condition":{"description":"@deprecated","type":"string"},"forceEdit":{"type":"boolean"},"key":{"type":"string"},"keyLabel":{"type":"string"},"operator":{"type":"string"},"origin":{"$ref":"#/components/schemas/FilterOrigin"},"value":{"type":"string"},"valueLabels":{"items":{"type":"string"},"type":"array"},"values":{"items":{"type":"string"},"type":"array"}},"required":["key","operator","value"],"type":"object"},"AdhocVariableKind":{"additionalProperties":false,"description":"Adhoc variable kind","properties":{"datasource":{"additionalProperties":false,"properties":{"name":{"type":"string"}},"type":"object"},"group":{"type":"string"},"kind":{"const":"AdhocVariable","type":"string"},"spec":{"$ref":"#/components/schemas/AdhocVariableSpec"}},"required":["kind","group","spec"],"type":"object"},"AdhocVariableSpec":{"additionalProperties":false,"description":"Adhoc variable specification","properties":{"allowCustomValue":{"default":true,"type":"boolean"},"baseFilters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"defaultKeys":{"items":{"$ref":"#/components/schemas/MetricFindValue"},"type":"array"},"description":{"type":"string"},"filters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","baseFilters","filters","defaultKeys","hide","skipUrlSync","allowCustomValue"],"type":"object"},"AnnotationEventFieldMapping":{"additionalProperties":false,"description":"Annotation event field mapping. Defines how to map a data frame field to an annotation event field.","properties":{"regex":{"description":"Regular expression to apply to the field value","type":"string"},"source":{"default":"field","description":"Source type for the field value","type":"string"},"value":{"description":"Constant value to use when source is \"text\"","type":"string"}},"type":"object"},"AnnotationPanelFilter":{"additionalProperties":false,"properties":{"exclude":{"default":false,"description":"Should the specified panels be included or excluded","type":"boolean"},"ids":{"description":"Panel IDs that should be included or excluded","items":{"type":"integer"},"type":"array"}},"required":["ids"],"type":"object"},"AnnotationQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"AnnotationQuery","type":"string"},"spec":{"$ref":"#/components/schemas/AnnotationQuerySpec"}},"required":["kind","spec"],"type":"object"},"AnnotationQueryPlacement":{"const":"inControlsMenu","description":"Annotation Query placement. Defines where the annotation query should be displayed.\n- \"inControlsMenu\" renders the annotation query in the dashboard controls dropdown menu","type":"string"},"AnnotationQuerySpec":{"additionalProperties":false,"properties":{"builtIn":{"default":false,"type":"boolean"},"enable":{"type":"boolean"},"filter":{"$ref":"#/components/schemas/AnnotationPanelFilter"},"hide":{"type":"boolean"},"iconColor":{"type":"string"},"legacyOptions":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"Catch-all field for datasource-specific properties. Should not be available in as code tooling.","type":"object"},"mappings":{"additionalProperties":{"$ref":"#/components/schemas/AnnotationEventFieldMapping"},"description":"Mappings define how to convert data frame fields to annotation event fields.","type":"object"},"name":{"type":"string"},"placement":{"$ref":"#/components/schemas/AnnotationQueryPlacement","description":"Placement can be used to display the annotation query somewhere else on the dashboard other than the default location."},"query":{"$ref":"#/components/schemas/DataQueryKind"}},"required":["query","enable","hide","iconColor","name"],"type":"object"},"AutoGridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutItemSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"element":{"$ref":"#/components/schemas/ElementReference"},"repeat":{"$ref":"#/components/schemas/AutoGridRepeatOptions"}},"required":["element"],"type":"object"},"AutoGridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutSpec":{"additionalProperties":false,"properties":{"columnWidth":{"type":"number"},"columnWidthMode":{"default":"standard","enum":["narrow","standard","wide","custom"],"type":"string"},"fillScreen":{"default":false,"type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/AutoGridLayoutItemKind"},"type":"array"},"maxColumnCount":{"default":3,"type":"number"},"rowHeight":{"type":"number"},"rowHeightMode":{"default":"standard","enum":["short","standard","tall","custom"],"type":"string"}},"required":["columnWidthMode","rowHeightMode","items"],"type":"object"},"AutoGridRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"ConditionalRenderingDataKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingData","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingDataSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingDataSpec":{"additionalProperties":false,"properties":{"value":{"type":"boolean"}},"required":["value"],"type":"object"},"ConditionalRenderingGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingGroup","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingGroupSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingGroupSpec":{"additionalProperties":false,"properties":{"condition":{"enum":["and","or"],"type":"string"},"items":{"items":{"oneOf":[{"$ref":"#/components/schemas/ConditionalRenderingVariableKind"},{"$ref":"#/components/schemas/ConditionalRenderingDataKind"},{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeKind"}]},"type":"array"},"visibility":{"enum":["show","hide"],"type":"string"}},"required":["visibility","condition","items"],"type":"object"},"ConditionalRenderingTimeRangeSizeKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingTimeRangeSize","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingTimeRangeSizeSpec":{"additionalProperties":false,"properties":{"value":{"type":"string"}},"required":["value"],"type":"object"},"ConditionalRenderingVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingVariableSpec":{"additionalProperties":false,"properties":{"operator":{"enum":["equals","notEquals","matches","notMatches"],"type":"string"},"value":{"type":"string"},"variable":{"type":"string"}},"required":["variable","operator","value"],"type":"object"},"ConstantVariableKind":{"additionalProperties":false,"description":"Constant variable kind","properties":{"kind":{"const":"ConstantVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConstantVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConstantVariableSpec":{"additionalProperties":false,"description":"Constant variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","hide","skipUrlSync"],"type":"object"},"ConversionStatus":{"additionalProperties":false,"description":"ConversionStatus is the status of the conversion of the dashboard.","properties":{"error":{"description":"The error message from the conversion.\nEmpty if the conversion has not failed.","type":"string"},"failed":{"description":"Whether from another version has failed.\nIf true, means that the dashboard is not valid,\nand the caller should instead fetch the stored version.","type":"boolean"},"source":{"additionalProperties":{},"description":"The original value map[string]any","type":"object"},"storedVersion":{"description":"The version which was stored when the dashboard was created / updated.\nFetching this version should always succeed.","type":"string"}},"required":["failed"],"type":"object"},"CustomVariableKind":{"additionalProperties":false,"description":"Custom variable kind","properties":{"kind":{"const":"CustomVariable","type":"string"},"spec":{"$ref":"#/components/schemas/CustomVariableSpec"}},"required":["kind","spec"],"type":"object"},"CustomVariableSpec":{"additionalProperties":false,"description":"Custom variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"Dashboard":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"DashboardCursorSync":{"description":"\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip.","enum":["Crosshair","Tooltip","Off"],"type":"string"},"DashboardLink":{"additionalProperties":false,"description":"Links with references to other dashboards or external resources","properties":{"asDropdown":{"default":false,"description":"If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards","type":"boolean"},"icon":{"description":"Icon name to be displayed with the link","type":"string"},"includeVars":{"default":false,"description":"If true, includes current template variables values in the link as query params","type":"boolean"},"keepTime":{"default":false,"description":"If true, includes current time range in the link as query params","type":"boolean"},"placement":{"$ref":"#/components/schemas/DashboardLinkPlacement","description":"Placement can be used to display the link somewhere else on the dashboard other than above the visualisations."},"tags":{"description":"List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards","items":{"type":"string"},"type":"array"},"targetBlank":{"default":false,"description":"If true, the link will be opened in a new tab","type":"boolean"},"title":{"description":"Title to display with the link","type":"string"},"tooltip":{"description":"Tooltip to display when the user hovers their mouse over it","type":"string"},"type":{"$ref":"#/components/schemas/DashboardLinkType","description":"Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)\nFIXME: The type is generated as ` + "`" + `type: DashboardLinkType | dashboardLinkType.Link;` + "`" + ` but it should be ` + "`" + `type: DashboardLinkType` + "`" + `"},"url":{"description":"Link URL. Only required/valid if the type is link","type":"string"}},"required":["title","type","icon","tooltip","tags","asDropdown","targetBlank","includeVars","keepTime"],"type":"object"},"DashboardLinkPlacement":{"const":"inControlsMenu","description":"Dashboard Link placement. Defines where the link should be displayed.\n- \"inControlsMenu\" renders the link in bottom part of the dashboard controls dropdown menu","type":"string"},"DashboardLinkType":{"description":"Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)","enum":["link","dashboards"],"type":"string"},"DataLink":{"additionalProperties":false,"properties":{"targetBlank":{"type":"boolean"},"title":{"type":"string"},"url":{"type":"string"}},"required":["title","url"],"type":"object"},"DataQueryKind":{"additionalProperties":false,"properties":{"datasource":{"additionalProperties":false,"description":"New type for datasource reference\nNot creating a new type until we figure out how to handle DS refs for group by, adhoc, and every place that uses DataSourceRef in TS.","properties":{"name":{"type":"string"}},"type":"object"},"group":{"type":"string"},"kind":{"const":"DataQuery","type":"string"},"spec":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"version":{"default":"v0","type":"string"}},"required":["kind","group","version","spec"],"type":"object"},"DataTopic":{"description":"A topic is attached to DataFrame metadata in query results.\nThis specifies where the data should be used.","enum":["series","annotations","alertStates"],"type":"string"},"DataTransformerConfig":{"additionalProperties":false,"description":"Transformations allow to manipulate data returned by a query before the system applies a visualization.\nUsing transformations you can: rename fields, join time series data, perform mathematical operations across queries,\nuse the output of one transformation as the input to another transformation, etc.","properties":{"disabled":{"description":"Disabled transformations are skipped","type":"boolean"},"filter":{"$ref":"#/components/schemas/MatcherConfig","description":"Optional frame matcher. When missing it will be applied to all results"},"id":{"description":"Unique identifier of transformer","type":"string"},"options":{"additionalProperties":{},"description":"Options to be passed to the transformer\nValid options depend on the transformer id","type":"object"},"topic":{"$ref":"#/components/schemas/DataTopic","description":"Where to pull DataFrames from as input to transformation"}},"required":["id","options"],"type":"object"},"DatasourceVariableKind":{"additionalProperties":false,"description":"Datasource variable kind","properties":{"kind":{"const":"DatasourceVariable","type":"string"},"spec":{"$ref":"#/components/schemas/DatasourceVariableSpec"}},"required":["kind","spec"],"type":"object"},"DatasourceVariableSpec":{"additionalProperties":false,"description":"Datasource variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"pluginId":{"default":"","type":"string"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","pluginId","refresh","regex","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"DynamicConfigValue":{"additionalProperties":false,"properties":{"id":{"default":"","type":"string"},"value":{"additionalProperties":{},"type":"object"}},"required":["id"],"type":"object"},"Element":{"description":"Supported dashboard elements\n|* more element types in the future","oneOf":[{"$ref":"#/components/schemas/PanelKind"},{"$ref":"#/components/schemas/LibraryPanelKind"}]},"ElementReference":{"additionalProperties":false,"properties":{"kind":{"const":"ElementReference","type":"string"},"name":{"type":"string"}},"required":["kind","name"],"type":"object"},"FetchOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url"],"type":"object"},"FieldColor":{"additionalProperties":false,"description":"Map a field to a color.","properties":{"fixedColor":{"description":"The fixed color value for fixed or shades color modes.","type":"string"},"mode":{"$ref":"#/components/schemas/FieldColorModeId","description":"The main color scheme mode."},"seriesBy":{"$ref":"#/components/schemas/FieldColorSeriesByMode","description":"Some visualizations need to know how to assign a series color from by value color schemes."}},"required":["mode"],"type":"object"},"FieldColorModeId":{"description":"Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value.\nContinuous color interpolates a color using the percentage of a value relative to min and max.\nAccepted values are:\n` + "`" + `thresholds` + "`" + `: From thresholds. Informs Grafana to take the color from the matching threshold\n` + "`" + `palette-classic` + "`" + `: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `palette-classic-by-name` + "`" + `: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `continuous-viridis` + "`" + `: Continuous Viridis palette mode\n` + "`" + `continuous-magma` + "`" + `: Continuous Magma palette mode\n` + "`" + `continuous-plasma` + "`" + `: Continuous Plasma palette mode\n` + "`" + `continuous-inferno` + "`" + `: Continuous Inferno palette mode\n` + "`" + `continuous-cividis` + "`" + `: Continuous Cividis palette mode\n` + "`" + `continuous-GrYlRd` + "`" + `: Continuous Green-Yellow-Red palette mode\n` + "`" + `continuous-RdYlGr` + "`" + `: Continuous Red-Yellow-Green palette mode\n` + "`" + `continuous-BlYlRd` + "`" + `: Continuous Blue-Yellow-Red palette mode\n` + "`" + `continuous-YlRd` + "`" + `: Continuous Yellow-Red palette mode\n` + "`" + `continuous-BlPu` + "`" + `: Continuous Blue-Purple palette mode\n` + "`" + `continuous-YlBl` + "`" + `: Continuous Yellow-Blue palette mode\n` + "`" + `continuous-blues` + "`" + `: Continuous Blue palette mode\n` + "`" + `continuous-reds` + "`" + `: Continuous Red palette mode\n` + "`" + `continuous-greens` + "`" + `: Continuous Green palette mode\n` + "`" + `continuous-purples` + "`" + `: Continuous Purple palette mode\n` + "`" + `shades` + "`" + `: Shades of a single color. Specify a single color, useful in an override rule.\n` + "`" + `fixed` + "`" + `: Fixed color mode. Specify a single color, useful in an override rule.","enum":["thresholds","palette-classic","palette-classic-by-name","continuous-viridis","continuous-magma","continuous-plasma","continuous-inferno","continuous-cividis","continuous-GrYlRd","continuous-RdYlGr","continuous-BlYlRd","continuous-YlRd","continuous-BlPu","continuous-YlBl","continuous-blues","continuous-reds","continuous-greens","continuous-purples","fixed","shades"],"type":"string"},"FieldColorSeriesByMode":{"description":"Defines how to assign a series color from \"by value\" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value.","enum":["min","max","last"],"type":"string"},"FieldConfig":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"actions":{"description":"Define interactive HTTP requests that can be triggered from data visualizations.","items":{"$ref":"#/components/schemas/Action"},"type":"array"},"color":{"$ref":"#/components/schemas/FieldColor","description":"Panel color configuration"},"custom":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"custom is specified by the FieldConfig field\nin panel plugin schemas.","type":"object"},"decimals":{"description":"Specify the number of decimals Grafana includes in the rendered value.\nIf you leave this field blank, Grafana automatically truncates the number of decimals based on the value.\nFor example 1.1234 will display as 1.12 and 100.456 will display as 100.\nTo display all decimals, set the unit to ` + "`" + `String` + "`" + `.","type":"number"},"description":{"description":"Human readable field metadata","type":"string"},"displayName":{"description":"The display value for this field. This supports template variables blank is auto","type":"string"},"displayNameFromDS":{"description":"This can be used by data sources that return and explicit naming structure for values and labels\nWhen this property is configured, this value is used rather than the default naming strategy.","type":"string"},"filterable":{"description":"True if data source field supports ad-hoc filters","type":"boolean"},"links":{"description":"The behavior when clicking on a result","items":{"additionalProperties":{},"type":"object"},"type":"array"},"mappings":{"description":"Convert input values into a display string","items":{"$ref":"#/components/schemas/ValueMapping"},"type":"array"},"max":{"description":"The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"min":{"description":"The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"noValue":{"description":"Alternative to empty string","type":"string"},"path":{"description":"An explicit path to the field in the datasource. When the frame meta includes a path,\nThis will default to ` + "`" + `${frame.meta.path}/${field.name}\n\nWhen defined, this value can be used as an identifier within the datasource scope, and\nmay be used to update the results","type":"string"},"thresholds":{"$ref":"#/components/schemas/ThresholdsConfig","description":"Map numeric values to states"},"unit":{"description":"Unit a field should use. The unit you select is applied to all fields except time.\nYou can use the units ID availables in Grafana or a custom unit.\nAvailable units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts\nAs custom unit, you can use the following formats:\n` + "`" + `suffix:\u003csuffix\u003e` + "`" + ` for custom unit that should go after value.\n` + "`" + `prefix:\u003cprefix\u003e` + "`" + ` for custom unit that should go before value.\n` + "`" + `time:\u003cformat\u003e` + "`" + ` For custom date time formats type for example ` + "`" + `time:YYYY-MM-DD` + "`" + `.\n` + "`" + `si:\u003cbase scale\u003e\u003cunit characters\u003e` + "`" + ` for custom SI units. For example: ` + "`" + `si: mF` + "`" + `. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.\n` + "`" + `count:\u003cunit\u003e` + "`" + ` for a custom count unit.\n` + "`" + `currency:\u003cunit\u003e` + "`" + ` for custom a currency unit.","type":"string"},"writeable":{"description":"True if data source can write a value to the path. Auth/authz are supported separately","type":"boolean"}},"type":"object"},"FieldConfigSource":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"defaults":{"$ref":"#/components/schemas/FieldConfig","description":"Defaults are the options applied to all fields."},"overrides":{"description":"Overrides are the options applied to specific fields overriding the defaults.","items":{"additionalProperties":false,"properties":{"__systemRef":{"description":"Describes config override rules created when interacting with Grafana.","type":"string"},"matcher":{"$ref":"#/components/schemas/MatcherConfig"},"properties":{"items":{"$ref":"#/components/schemas/DynamicConfigValue"},"type":"array"}},"required":["matcher","properties"],"type":"object"},"type":"array"}},"required":["defaults","overrides"],"type":"object"},"FilterOrigin":{"const":"dashboard","description":"Determine the origin of the adhoc variable filter","type":"string"},"GridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutItemSpec":{"additionalProperties":false,"properties":{"element":{"$ref":"#/components/schemas/ElementReference","description":"reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference"},"height":{"type":"integer"},"repeat":{"$ref":"#/components/schemas/RepeatOptions"},"width":{"type":"integer"},"x":{"type":"integer"},"y":{"type":"integer"}},"required":["x","y","width","height","element"],"type":"object"},"GridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutSpec":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/GridLayoutItemKind"},"type":"array"}},"required":["items"],"type":"object"},"GroupByVariableKind":{"additionalProperties":false,"description":"Group variable kind","properties":{"datasource":{"additionalProperties":false,"properties":{"name":{"type":"string"}},"type":"object"},"group":{"type":"string"},"kind":{"const":"GroupByVariable","type":"string"},"spec":{"$ref":"#/components/schemas/GroupByVariableSpec"}},"required":["kind","group","spec"],"type":"object"},"GroupByVariableSpec":{"additionalProperties":false,"description":"GroupBy variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"defaultValue":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","options","multi","hide","skipUrlSync"],"type":"object"},"HttpRequestMethod":{"enum":["GET","PUT","POST","DELETE","PATCH"],"type":"string"},"InfinityOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"datasourceUid":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url","datasourceUid"],"type":"object"},"IntervalVariableKind":{"additionalProperties":false,"description":"Interval variable kind","properties":{"kind":{"const":"IntervalVariable","type":"string"},"spec":{"$ref":"#/components/schemas/IntervalVariableSpec"}},"required":["kind","spec"],"type":"object"},"IntervalVariableSpec":{"additionalProperties":false,"description":"Interval variable specification","properties":{"auto":{"default":false,"type":"boolean"},"auto_count":{"default":0,"type":"integer"},"auto_min":{"default":"","type":"string"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"refresh":{"const":"onTimeRangeChanged","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","options","auto","auto_min","auto_count","refresh","hide","skipUrlSync"],"type":"object"},"LibraryPanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"LibraryPanel","type":"string"},"spec":{"$ref":"#/components/schemas/LibraryPanelKindSpec"}},"required":["kind","spec"],"type":"object"},"LibraryPanelKindSpec":{"additionalProperties":false,"properties":{"id":{"description":"Panel ID for the library panel in the dashboard","type":"number"},"libraryPanel":{"$ref":"#/components/schemas/LibraryPanelRef"},"title":{"description":"Title for the library panel in the dashboard","type":"string"}},"required":["id","title","libraryPanel"],"type":"object"},"LibraryPanelRef":{"additionalProperties":false,"description":"A library panel is a reusable panel that you can use in any dashboard.\nWhen you make a change to a library panel, that change propagates to all instances of where the panel is used.\nLibrary panels streamline reuse of panels across multiple dashboards.","properties":{"name":{"description":"Library panel name","type":"string"},"uid":{"description":"Library panel uid","type":"string"}},"required":["name","uid"],"type":"object"},"MappingType":{"description":"Supported value mapping types\n` + "`" + `value` + "`" + `: Maps text values to a color or different display text and color. For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.\n` + "`" + `range` + "`" + `: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.\n` + "`" + `regex` + "`" + `: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.\n` + "`" + `special` + "`" + `: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.","enum":["value","range","regex","special"],"type":"string"},"MatcherConfig":{"additionalProperties":false,"description":"Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.\nIt comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.","properties":{"id":{"default":"","description":"The matcher id. This is used to find the matcher implementation from registry.","type":"string"},"options":{"additionalProperties":{},"description":"The matcher options. This is specific to the matcher implementation.","type":"object"}},"required":["id"],"type":"object"},"MetricFindValue":{"additionalProperties":false,"description":"Define the MetricFindValue type","properties":{"expandable":{"type":"boolean"},"group":{"type":"string"},"text":{"type":"string"},"value":{"oneOf":[{"type":"string"},{"type":"number"}]}},"required":["text"],"type":"object"},"PanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"Panel","type":"string"},"spec":{"$ref":"#/components/schemas/PanelSpec"}},"required":["kind","spec"],"type":"object"},"PanelQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"PanelQuery","type":"string"},"spec":{"$ref":"#/components/schemas/PanelQuerySpec"}},"required":["kind","spec"],"type":"object"},"PanelQuerySpec":{"additionalProperties":false,"properties":{"hidden":{"type":"boolean"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refId":{"default":"A","type":"string"}},"required":["query","refId","hidden"],"type":"object"},"PanelSpec":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QueryGroupKind"},"description":{"type":"string"},"id":{"type":"number"},"links":{"items":{"$ref":"#/components/schemas/DataLink"},"type":"array"},"title":{"type":"string"},"transparent":{"type":"boolean"},"vizConfig":{"$ref":"#/components/schemas/VizConfigKind"}},"required":["id","title","description","links","data","vizConfig"],"type":"object"},"QueryGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"QueryGroup","type":"string"},"spec":{"$ref":"#/components/schemas/QueryGroupSpec"}},"required":["kind","spec"],"type":"object"},"QueryGroupSpec":{"additionalProperties":false,"properties":{"queries":{"items":{"$ref":"#/components/schemas/PanelQueryKind"},"type":"array"},"queryOptions":{"$ref":"#/components/schemas/QueryOptionsSpec"},"transformations":{"items":{"$ref":"#/components/schemas/TransformationKind"},"type":"array"}},"required":["queries","transformations","queryOptions"],"type":"object"},"QueryOptionsSpec":{"additionalProperties":false,"properties":{"cacheTimeout":{"type":"string"},"hideTimeOverride":{"type":"boolean"},"interval":{"type":"string"},"maxDataPoints":{"type":"integer"},"queryCachingTTL":{"type":"integer"},"timeCompare":{"type":"string"},"timeFrom":{"type":"string"},"timeShift":{"type":"string"}},"type":"object"},"QueryVariableKind":{"additionalProperties":false,"description":"Query variable kind","properties":{"kind":{"const":"QueryVariable","type":"string"},"spec":{"$ref":"#/components/schemas/QueryVariableSpec"}},"required":["kind","spec"],"type":"object"},"QueryVariableSpec":{"additionalProperties":false,"description":"Query variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"definition":{"type":"string"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"placeholder":{"type":"string"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"},"sort":{"$ref":"#/components/schemas/VariableSort"},"staticOptions":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"staticOptionsOrder":{"enum":["before","after","sorted"],"type":"string"}},"required":["name","current","hide","refresh","skipUrlSync","query","regex","sort","options","multi","includeAll","allowCustomValue"],"type":"object"},"RangeMap":{"additionalProperties":false,"description":"Maps numerical ranges to a display text and color.\nFor example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.","properties":{"options":{"additionalProperties":false,"description":"Range to match against and the result to apply when the value is within the range","properties":{"from":{"description":"Min value of the range. It can be null which means -Infinity","type":"number"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value is within the range"},"to":{"description":"Max value of the range. It can be null which means +Infinity","type":"number"}},"required":["from","to","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RegexMap":{"additionalProperties":false,"description":"Maps regular expressions to replacement text and a color.\nFor example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.","properties":{"options":{"additionalProperties":false,"description":"Regular expression to match against and the result to apply when the value matches the regex","properties":{"pattern":{"description":"Regular expression to match against","type":"string"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the regex"}},"required":["pattern","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RepeatMode":{"const":"variable","description":"other repeat modes will be added in the future: label, frame","type":"string"},"RepeatOptions":{"additionalProperties":false,"properties":{"direction":{"enum":["h","v"],"type":"string"},"maxPerRow":{"type":"integer"},"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayoutRow","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutRowSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowSpec":{"additionalProperties":false,"properties":{"collapse":{"type":"boolean"},"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"fillScreen":{"type":"boolean"},"hideHeader":{"type":"boolean"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/RowRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"RowsLayoutSpec":{"additionalProperties":false,"properties":{"rows":{"items":{"$ref":"#/components/schemas/RowsLayoutRowKind"},"type":"array"}},"required":["rows"],"type":"object"},"SpecialValueMap":{"additionalProperties":false,"description":"Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color.\nSee SpecialValueMatch to see the list of special values.\nFor example, you can configure a special value mapping so that null values appear as N/A.","properties":{"options":{"additionalProperties":false,"properties":{"match":{"$ref":"#/components/schemas/SpecialValueMatch","description":"Special value to match against"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the special value"}},"required":["match","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"SpecialValueMatch":{"description":"Special value types supported by the ` + "`" + `SpecialValueMap` + "`" + `","enum":["true","false","null","nan","null+nan","empty"],"type":"string"},"SwitchVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"SwitchVariable","type":"string"},"spec":{"$ref":"#/components/schemas/SwitchVariableSpec"}},"required":["kind","spec"],"type":"object"},"SwitchVariableSpec":{"additionalProperties":false,"properties":{"current":{"default":"false","type":"string"},"description":{"type":"string"},"disabledValue":{"default":"false","type":"string"},"enabledValue":{"default":"true","type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","enabledValue","disabledValue","hide","skipUrlSync"],"type":"object"},"TabRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"TabsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutSpec":{"additionalProperties":false,"properties":{"tabs":{"items":{"$ref":"#/components/schemas/TabsLayoutTabKind"},"type":"array"}},"required":["tabs"],"type":"object"},"TabsLayoutTabKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayoutTab","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutTabSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutTabSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/TabRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"TextVariableKind":{"additionalProperties":false,"description":"Text variable kind","properties":{"kind":{"const":"TextVariable","type":"string"},"spec":{"$ref":"#/components/schemas/TextVariableSpec"}},"required":["kind","spec"],"type":"object"},"TextVariableSpec":{"additionalProperties":false,"description":"Text variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","query","hide","skipUrlSync"],"type":"object"},"Threshold":{"additionalProperties":false,"properties":{"color":{"type":"string"},"value":{"description":"Value null means -Infinity","type":"number"}},"required":["value","color"],"type":"object"},"ThresholdsConfig":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/ThresholdsMode"},"steps":{"items":{"$ref":"#/components/schemas/Threshold"},"type":"array"}},"required":["mode","steps"],"type":"object"},"ThresholdsMode":{"enum":["absolute","percentage"],"type":"string"},"TimeRangeOption":{"additionalProperties":false,"properties":{"display":{"default":"Last 6 hours","type":"string"},"from":{"default":"now-6h","type":"string"},"to":{"default":"now","type":"string"}},"required":["display","from","to"],"type":"object"},"TimeSettingsSpec":{"additionalProperties":false,"description":"Time configuration\nIt defines the default time config for the time picker, the refresh picker for the specific dashboard.","properties":{"autoRefresh":{"default":"","description":"Refresh rate of dashboard. Represented via interval string, e.g. \"5s\", \"1m\", \"1h\", \"1d\".\nv1: refresh","type":"string"},"autoRefreshIntervals":{"default":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"description":"Interval options available in the refresh picker dropdown.\nv1: timepicker.refresh_intervals","items":{"type":"string"},"type":"array"},"fiscalYearStartMonth":{"default":0,"description":"The month that the fiscal year starts on. 0 = January, 11 = December","type":"integer"},"from":{"default":"now-6h","description":"Start time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"hideTimepicker":{"default":false,"description":"Whether timepicker is visible or not.\nv1: timepicker.hidden","type":"boolean"},"nowDelay":{"description":"Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values.\nv1: timepicker.nowDelay","type":"string"},"quickRanges":{"description":"Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.\nv1: timepicker.quick_ranges , not exposed in the UI","items":{"$ref":"#/components/schemas/TimeRangeOption"},"type":"array"},"timezone":{"default":"browser","description":"Timezone of dashboard. Accepted values are IANA TZDB zone ID or \"browser\" or \"utc\".","type":"string"},"to":{"default":"now","description":"End time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"weekStart":{"description":"Day when the week starts. Expressed by the name of the day in lowercase, e.g. \"monday\".","enum":["saturday","monday","sunday"],"type":"string"}},"required":["from","to","autoRefresh","autoRefreshIntervals","hideTimepicker","fiscalYearStartMonth"],"type":"object"},"TransformationKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a TransformationKind is the transformation ID","type":"string"},"spec":{"$ref":"#/components/schemas/DataTransformerConfig"}},"required":["kind","spec"],"type":"object"},"ValueMap":{"additionalProperties":false,"description":"Maps text values to a color or different display text and color.\nFor example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.","properties":{"options":{"additionalProperties":{"$ref":"#/components/schemas/ValueMappingResult"},"description":"Map with \u003cvalue_to_match\u003e: ValueMappingResult. For example: { \"10\": { text: \"Perfection!\", color: \"green\" } }","type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"ValueMapping":{"oneOf":[{"$ref":"#/components/schemas/ValueMap"},{"$ref":"#/components/schemas/RangeMap"},{"$ref":"#/components/schemas/RegexMap"},{"$ref":"#/components/schemas/SpecialValueMap"}]},"ValueMappingResult":{"additionalProperties":false,"description":"Result used as replacement with text and color when the value matches","properties":{"color":{"description":"Text to use when the value matches","type":"string"},"icon":{"description":"Icon to display when the value matches. Only specific visualizations.","type":"string"},"index":{"description":"Position in the mapping array. Only used internally.","type":"integer"},"text":{"description":"Text to display when the value matches","type":"string"}},"type":"object"},"VariableHide":{"description":"Determine if the variable shows on dashboard\nAccepted values are ` + "`" + `dontHide` + "`" + ` (show label and value), ` + "`" + `hideLabel` + "`" + ` (show value only), ` + "`" + `hideVariable` + "`" + ` (show nothing), ` + "`" + `inControlsMenu` + "`" + ` (show in a drop-down menu).","enum":["dontHide","hideLabel","hideVariable","inControlsMenu"],"type":"string"},"VariableKind":{"oneOf":[{"$ref":"#/components/schemas/QueryVariableKind"},{"$ref":"#/components/schemas/TextVariableKind"},{"$ref":"#/components/schemas/ConstantVariableKind"},{"$ref":"#/components/schemas/DatasourceVariableKind"},{"$ref":"#/components/schemas/IntervalVariableKind"},{"$ref":"#/components/schemas/CustomVariableKind"},{"$ref":"#/components/schemas/GroupByVariableKind"},{"$ref":"#/components/schemas/AdhocVariableKind"},{"$ref":"#/components/schemas/SwitchVariableKind"}]},"VariableOption":{"additionalProperties":false,"description":"Variable option specification","properties":{"selected":{"description":"Whether the option is selected or not","type":"boolean"},"text":{"description":"Text to be displayed for the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]},"value":{"description":"Value of the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]}},"required":["text","value"],"type":"object"},"VariableRefresh":{"description":"Options to config when to refresh a variable\n` + "`" + `never` + "`" + `: Never refresh the variable\n` + "`" + `onDashboardLoad` + "`" + `: Queries the data source every time the dashboard loads.\n` + "`" + `onTimeRangeChanged` + "`" + `: Queries the data source when the dashboard time range changes.","enum":["never","onDashboardLoad","onTimeRangeChanged"],"type":"string"},"VariableSort":{"description":"Sort variable options\nAccepted values are:\n` + "`" + `disabled` + "`" + `: No sorting\n` + "`" + `alphabeticalAsc` + "`" + `: Alphabetical ASC\n` + "`" + `alphabeticalDesc` + "`" + `: Alphabetical DESC\n` + "`" + `numericalAsc` + "`" + `: Numerical ASC\n` + "`" + `numericalDesc` + "`" + `: Numerical DESC\n` + "`" + `alphabeticalCaseInsensitiveAsc` + "`" + `: Alphabetical Case Insensitive ASC\n` + "`" + `alphabeticalCaseInsensitiveDesc` + "`" + `: Alphabetical Case Insensitive DESC\n` + "`" + `naturalAsc` + "`" + `: Natural ASC\n` + "`" + `naturalDesc` + "`" + `: Natural DESC\nVariableSort enum with default value","enum":["disabled","alphabeticalAsc","alphabeticalDesc","numericalAsc","numericalDesc","alphabeticalCaseInsensitiveAsc","alphabeticalCaseInsensitiveDesc","naturalAsc","naturalDesc"],"type":"string"},"VizConfigKind":{"additionalProperties":false,"properties":{"group":{"description":"The group is the plugin ID","type":"string"},"kind":{"const":"VizConfig","type":"string"},"spec":{"$ref":"#/components/schemas/VizConfigSpec"},"version":{"type":"string"}},"required":["kind","group","version","spec"],"type":"object"},"VizConfigSpec":{"additionalProperties":false,"description":"--- Kinds ---","properties":{"fieldConfig":{"$ref":"#/components/schemas/FieldConfigSource"},"options":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"}},"required":["options","fieldConfig"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"annotations":{"items":{"$ref":"#/components/schemas/AnnotationQueryKind"},"type":"array"},"cursorSync":{"$ref":"#/components/schemas/DashboardCursorSync","default":"Off","description":"Configuration of dashboard cursor sync behavior.\n\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip."},"description":{"description":"Description of dashboard.","type":"string"},"editable":{"default":true,"description":"Whether a dashboard is editable or not.","type":"boolean"},"elements":{"additionalProperties":{"$ref":"#/components/schemas/Element"},"type":"object"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"links":{"description":"Links with references to other dashboards or external websites.","items":{"$ref":"#/components/schemas/DashboardLink"},"type":"array"},"liveNow":{"description":"When set to true, the dashboard will redraw panels at an interval matching the pixel width.\nThis will keep data \"moving left\" regardless of the query refresh rate. This setting helps\navoid dashboards presenting stale live data.","type":"boolean"},"preload":{"default":false,"description":"When set to true, the dashboard will load all panels in the dashboard when it's loaded.","type":"boolean"},"revision":{"description":"Plugins only. The version of the dashboard installed together with the plugin.\nThis is used to determine if the dashboard should be updated when the plugin is updated.","type":"integer"},"tags":{"description":"Tags associated with dashboard.","items":{"type":"string"},"type":"array"},"timeSettings":{"$ref":"#/components/schemas/TimeSettingsSpec"},"title":{"description":"Title of dashboard.","type":"string"},"variables":{"description":"Configured template variables.","items":{"$ref":"#/components/schemas/VariableKind"},"type":"array"}},"required":["annotations","cursorSync","elements","layout","links","preload","tags","timeSettings","title","variables"],"type":"object"},"status":{"additionalProperties":false,"properties":{"conversion":{"$ref":"#/components/schemas/ConversionStatus","description":"Optional conversion status."}},"type":"object"}}`) + rawSchemaDashboardv2beta1 = []byte(`{"Action":{"additionalProperties":false,"properties":{"confirmation":{"type":"string"},"fetch":{"$ref":"#/components/schemas/FetchOptions"},"infinity":{"$ref":"#/components/schemas/InfinityOptions"},"oneClick":{"type":"boolean"},"style":{"additionalProperties":false,"properties":{"backgroundColor":{"type":"string"}},"type":"object"},"title":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionType"},"variables":{"items":{"$ref":"#/components/schemas/ActionVariable"},"type":"array"}},"required":["type","title"],"type":"object"},"ActionType":{"enum":["fetch","infinity"],"type":"string"},"ActionVariable":{"additionalProperties":false,"properties":{"key":{"type":"string"},"name":{"type":"string"},"type":{"$ref":"#/components/schemas/ActionVariableType"}},"required":["key","name","type"],"type":"object"},"ActionVariableType":{"const":"string","description":"Action variable type","type":"string"},"AdHocFilterWithLabels":{"additionalProperties":false,"description":"Define the AdHocFilterWithLabels type","properties":{"condition":{"description":"@deprecated","type":"string"},"forceEdit":{"type":"boolean"},"key":{"type":"string"},"keyLabel":{"type":"string"},"operator":{"type":"string"},"origin":{"$ref":"#/components/schemas/FilterOrigin"},"value":{"type":"string"},"valueLabels":{"items":{"type":"string"},"type":"array"},"values":{"items":{"type":"string"},"type":"array"}},"required":["key","operator","value"],"type":"object"},"AdhocVariableKind":{"additionalProperties":false,"description":"Adhoc variable kind","properties":{"datasource":{"additionalProperties":false,"properties":{"name":{"type":"string"}},"type":"object"},"group":{"type":"string"},"kind":{"const":"AdhocVariable","type":"string"},"spec":{"$ref":"#/components/schemas/AdhocVariableSpec"}},"required":["kind","group","spec"],"type":"object"},"AdhocVariableSpec":{"additionalProperties":false,"description":"Adhoc variable specification","properties":{"allowCustomValue":{"default":true,"type":"boolean"},"baseFilters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"defaultKeys":{"items":{"$ref":"#/components/schemas/MetricFindValue"},"type":"array"},"description":{"type":"string"},"filters":{"items":{"$ref":"#/components/schemas/AdHocFilterWithLabels"},"type":"array"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","baseFilters","filters","defaultKeys","hide","skipUrlSync","allowCustomValue"],"type":"object"},"AnnotationEventFieldMapping":{"additionalProperties":false,"description":"Annotation event field mapping. Defines how to map a data frame field to an annotation event field.","properties":{"regex":{"description":"Regular expression to apply to the field value","type":"string"},"source":{"default":"field","description":"Source type for the field value","type":"string"},"value":{"description":"Constant value to use when source is \"text\"","type":"string"}},"type":"object"},"AnnotationPanelFilter":{"additionalProperties":false,"properties":{"exclude":{"default":false,"description":"Should the specified panels be included or excluded","type":"boolean"},"ids":{"description":"Panel IDs that should be included or excluded","items":{"type":"integer"},"type":"array"}},"required":["ids"],"type":"object"},"AnnotationQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"AnnotationQuery","type":"string"},"spec":{"$ref":"#/components/schemas/AnnotationQuerySpec"}},"required":["kind","spec"],"type":"object"},"AnnotationQueryPlacement":{"const":"inControlsMenu","description":"Annotation Query placement. Defines where the annotation query should be displayed.\n- \"inControlsMenu\" renders the annotation query in the dashboard controls dropdown menu","type":"string"},"AnnotationQuerySpec":{"additionalProperties":false,"properties":{"builtIn":{"default":false,"type":"boolean"},"enable":{"type":"boolean"},"filter":{"$ref":"#/components/schemas/AnnotationPanelFilter"},"hide":{"type":"boolean"},"iconColor":{"type":"string"},"legacyOptions":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"Catch-all field for datasource-specific properties. Should not be available in as code tooling.","type":"object"},"mappings":{"additionalProperties":{"$ref":"#/components/schemas/AnnotationEventFieldMapping"},"description":"Mappings define how to convert data frame fields to annotation event fields.","type":"object"},"name":{"type":"string"},"placement":{"$ref":"#/components/schemas/AnnotationQueryPlacement","description":"Placement can be used to display the annotation query somewhere else on the dashboard other than the default location."},"query":{"$ref":"#/components/schemas/DataQueryKind"}},"required":["query","enable","hide","iconColor","name"],"type":"object"},"AutoGridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutItemSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"element":{"$ref":"#/components/schemas/ElementReference"},"repeat":{"$ref":"#/components/schemas/AutoGridRepeatOptions"}},"required":["element"],"type":"object"},"AutoGridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"AutoGridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/AutoGridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"AutoGridLayoutSpec":{"additionalProperties":false,"properties":{"columnWidth":{"type":"number"},"columnWidthMode":{"default":"standard","enum":["narrow","standard","wide","custom"],"type":"string"},"fillScreen":{"default":false,"type":"boolean"},"items":{"items":{"$ref":"#/components/schemas/AutoGridLayoutItemKind"},"type":"array"},"maxColumnCount":{"default":3,"type":"number"},"rowHeight":{"type":"number"},"rowHeightMode":{"default":"standard","enum":["short","standard","tall","custom"],"type":"string"}},"required":["columnWidthMode","rowHeightMode","items"],"type":"object"},"AutoGridRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"ConditionalRenderingDataKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingData","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingDataSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingDataSpec":{"additionalProperties":false,"properties":{"value":{"type":"boolean"}},"required":["value"],"type":"object"},"ConditionalRenderingGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingGroup","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingGroupSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingGroupSpec":{"additionalProperties":false,"properties":{"condition":{"enum":["and","or"],"type":"string"},"items":{"items":{"oneOf":[{"$ref":"#/components/schemas/ConditionalRenderingVariableKind"},{"$ref":"#/components/schemas/ConditionalRenderingDataKind"},{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeKind"}]},"type":"array"},"visibility":{"enum":["show","hide"],"type":"string"}},"required":["visibility","condition","items"],"type":"object"},"ConditionalRenderingTimeRangeSizeKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingTimeRangeSize","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingTimeRangeSizeSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingTimeRangeSizeSpec":{"additionalProperties":false,"properties":{"value":{"type":"string"}},"required":["value"],"type":"object"},"ConditionalRenderingVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"ConditionalRenderingVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConditionalRenderingVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConditionalRenderingVariableSpec":{"additionalProperties":false,"properties":{"operator":{"enum":["equals","notEquals","matches","notMatches"],"type":"string"},"value":{"type":"string"},"variable":{"type":"string"}},"required":["variable","operator","value"],"type":"object"},"ConstantVariableKind":{"additionalProperties":false,"description":"Constant variable kind","properties":{"kind":{"const":"ConstantVariable","type":"string"},"spec":{"$ref":"#/components/schemas/ConstantVariableSpec"}},"required":["kind","spec"],"type":"object"},"ConstantVariableSpec":{"additionalProperties":false,"description":"Constant variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","hide","skipUrlSync"],"type":"object"},"ConversionStatus":{"additionalProperties":false,"description":"ConversionStatus is the status of the conversion of the dashboard.","properties":{"error":{"description":"The error message from the conversion.\nEmpty if the conversion has not failed.","type":"string"},"failed":{"description":"Whether from another version has failed.\nIf true, means that the dashboard is not valid,\nand the caller should instead fetch the stored version.","type":"boolean"},"source":{"additionalProperties":{},"description":"The original value map[string]any","type":"object"},"storedVersion":{"description":"The version which was stored when the dashboard was created / updated.\nFetching this version should always succeed.","type":"string"}},"required":["failed"],"type":"object"},"CustomVariableKind":{"additionalProperties":false,"description":"Custom variable kind","properties":{"kind":{"const":"CustomVariable","type":"string"},"spec":{"$ref":"#/components/schemas/CustomVariableSpec"}},"required":["kind","spec"],"type":"object"},"CustomVariableSpec":{"additionalProperties":false,"description":"Custom variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"},"valuesFormat":{"enum":["csv","json"],"type":"string"}},"required":["name","query","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"Dashboard":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"DashboardCursorSync":{"description":"\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip.","enum":["Crosshair","Tooltip","Off"],"type":"string"},"DashboardLink":{"additionalProperties":false,"description":"Links with references to other dashboards or external resources","properties":{"asDropdown":{"default":false,"description":"If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards","type":"boolean"},"icon":{"description":"Icon name to be displayed with the link","type":"string"},"includeVars":{"default":false,"description":"If true, includes current template variables values in the link as query params","type":"boolean"},"keepTime":{"default":false,"description":"If true, includes current time range in the link as query params","type":"boolean"},"placement":{"$ref":"#/components/schemas/DashboardLinkPlacement","description":"Placement can be used to display the link somewhere else on the dashboard other than above the visualisations."},"tags":{"description":"List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards","items":{"type":"string"},"type":"array"},"targetBlank":{"default":false,"description":"If true, the link will be opened in a new tab","type":"boolean"},"title":{"description":"Title to display with the link","type":"string"},"tooltip":{"description":"Tooltip to display when the user hovers their mouse over it","type":"string"},"type":{"$ref":"#/components/schemas/DashboardLinkType","description":"Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)\nFIXME: The type is generated as ` + "`" + `type: DashboardLinkType | dashboardLinkType.Link;` + "`" + ` but it should be ` + "`" + `type: DashboardLinkType` + "`" + `"},"url":{"description":"Link URL. Only required/valid if the type is link","type":"string"}},"required":["title","type","icon","tooltip","tags","asDropdown","targetBlank","includeVars","keepTime"],"type":"object"},"DashboardLinkPlacement":{"const":"inControlsMenu","description":"Dashboard Link placement. Defines where the link should be displayed.\n- \"inControlsMenu\" renders the link in bottom part of the dashboard controls dropdown menu","type":"string"},"DashboardLinkType":{"description":"Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)","enum":["link","dashboards"],"type":"string"},"DataLink":{"additionalProperties":false,"properties":{"targetBlank":{"type":"boolean"},"title":{"type":"string"},"url":{"type":"string"}},"required":["title","url"],"type":"object"},"DataQueryKind":{"additionalProperties":false,"properties":{"datasource":{"additionalProperties":false,"description":"New type for datasource reference\nNot creating a new type until we figure out how to handle DS refs for group by, adhoc, and every place that uses DataSourceRef in TS.","properties":{"name":{"type":"string"}},"type":"object"},"group":{"type":"string"},"kind":{"const":"DataQuery","type":"string"},"spec":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"version":{"default":"v0","type":"string"}},"required":["kind","group","version","spec"],"type":"object"},"DataTopic":{"description":"A topic is attached to DataFrame metadata in query results.\nThis specifies where the data should be used.","enum":["series","annotations","alertStates"],"type":"string"},"DataTransformerConfig":{"additionalProperties":false,"description":"Transformations allow to manipulate data returned by a query before the system applies a visualization.\nUsing transformations you can: rename fields, join time series data, perform mathematical operations across queries,\nuse the output of one transformation as the input to another transformation, etc.","properties":{"disabled":{"description":"Disabled transformations are skipped","type":"boolean"},"filter":{"$ref":"#/components/schemas/MatcherConfig","description":"Optional frame matcher. When missing it will be applied to all results"},"id":{"description":"Unique identifier of transformer","type":"string"},"options":{"additionalProperties":{},"description":"Options to be passed to the transformer\nValid options depend on the transformer id","type":"object"},"topic":{"$ref":"#/components/schemas/DataTopic","description":"Where to pull DataFrames from as input to transformation"}},"required":["id","options"],"type":"object"},"DatasourceVariableKind":{"additionalProperties":false,"description":"Datasource variable kind","properties":{"kind":{"const":"DatasourceVariable","type":"string"},"spec":{"$ref":"#/components/schemas/DatasourceVariableSpec"}},"required":["kind","spec"],"type":"object"},"DatasourceVariableSpec":{"additionalProperties":false,"description":"Datasource variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"pluginId":{"default":"","type":"string"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","pluginId","refresh","regex","current","options","multi","includeAll","hide","skipUrlSync","allowCustomValue"],"type":"object"},"DynamicConfigValue":{"additionalProperties":false,"properties":{"id":{"default":"","type":"string"},"value":{"additionalProperties":{},"type":"object"}},"required":["id"],"type":"object"},"Element":{"description":"Supported dashboard elements\n|* more element types in the future","oneOf":[{"$ref":"#/components/schemas/PanelKind"},{"$ref":"#/components/schemas/LibraryPanelKind"}]},"ElementReference":{"additionalProperties":false,"properties":{"kind":{"const":"ElementReference","type":"string"},"name":{"type":"string"}},"required":["kind","name"],"type":"object"},"FetchOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url"],"type":"object"},"FieldColor":{"additionalProperties":false,"description":"Map a field to a color.","properties":{"fixedColor":{"description":"The fixed color value for fixed or shades color modes.","type":"string"},"mode":{"$ref":"#/components/schemas/FieldColorModeId","description":"The main color scheme mode."},"seriesBy":{"$ref":"#/components/schemas/FieldColorSeriesByMode","description":"Some visualizations need to know how to assign a series color from by value color schemes."}},"required":["mode"],"type":"object"},"FieldColorModeId":{"description":"Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value.\nContinuous color interpolates a color using the percentage of a value relative to min and max.\nAccepted values are:\n` + "`" + `thresholds` + "`" + `: From thresholds. Informs Grafana to take the color from the matching threshold\n` + "`" + `palette-classic` + "`" + `: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `palette-classic-by-name` + "`" + `: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations\n` + "`" + `continuous-viridis` + "`" + `: Continuous Viridis palette mode\n` + "`" + `continuous-magma` + "`" + `: Continuous Magma palette mode\n` + "`" + `continuous-plasma` + "`" + `: Continuous Plasma palette mode\n` + "`" + `continuous-inferno` + "`" + `: Continuous Inferno palette mode\n` + "`" + `continuous-cividis` + "`" + `: Continuous Cividis palette mode\n` + "`" + `continuous-GrYlRd` + "`" + `: Continuous Green-Yellow-Red palette mode\n` + "`" + `continuous-RdYlGr` + "`" + `: Continuous Red-Yellow-Green palette mode\n` + "`" + `continuous-BlYlRd` + "`" + `: Continuous Blue-Yellow-Red palette mode\n` + "`" + `continuous-YlRd` + "`" + `: Continuous Yellow-Red palette mode\n` + "`" + `continuous-BlPu` + "`" + `: Continuous Blue-Purple palette mode\n` + "`" + `continuous-YlBl` + "`" + `: Continuous Yellow-Blue palette mode\n` + "`" + `continuous-blues` + "`" + `: Continuous Blue palette mode\n` + "`" + `continuous-reds` + "`" + `: Continuous Red palette mode\n` + "`" + `continuous-greens` + "`" + `: Continuous Green palette mode\n` + "`" + `continuous-purples` + "`" + `: Continuous Purple palette mode\n` + "`" + `shades` + "`" + `: Shades of a single color. Specify a single color, useful in an override rule.\n` + "`" + `fixed` + "`" + `: Fixed color mode. Specify a single color, useful in an override rule.","enum":["thresholds","palette-classic","palette-classic-by-name","continuous-viridis","continuous-magma","continuous-plasma","continuous-inferno","continuous-cividis","continuous-GrYlRd","continuous-RdYlGr","continuous-BlYlRd","continuous-YlRd","continuous-BlPu","continuous-YlBl","continuous-blues","continuous-reds","continuous-greens","continuous-purples","fixed","shades"],"type":"string"},"FieldColorSeriesByMode":{"description":"Defines how to assign a series color from \"by value\" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value.","enum":["min","max","last"],"type":"string"},"FieldConfig":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"actions":{"description":"Define interactive HTTP requests that can be triggered from data visualizations.","items":{"$ref":"#/components/schemas/Action"},"type":"array"},"color":{"$ref":"#/components/schemas/FieldColor","description":"Panel color configuration"},"custom":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"custom is specified by the FieldConfig field\nin panel plugin schemas.","type":"object"},"decimals":{"description":"Specify the number of decimals Grafana includes in the rendered value.\nIf you leave this field blank, Grafana automatically truncates the number of decimals based on the value.\nFor example 1.1234 will display as 1.12 and 100.456 will display as 100.\nTo display all decimals, set the unit to ` + "`" + `String` + "`" + `.","type":"number"},"description":{"description":"Human readable field metadata","type":"string"},"displayName":{"description":"The display value for this field. This supports template variables blank is auto","type":"string"},"displayNameFromDS":{"description":"This can be used by data sources that return and explicit naming structure for values and labels\nWhen this property is configured, this value is used rather than the default naming strategy.","type":"string"},"filterable":{"description":"True if data source field supports ad-hoc filters","type":"boolean"},"links":{"description":"The behavior when clicking on a result","items":{"additionalProperties":{},"type":"object"},"type":"array"},"mappings":{"description":"Convert input values into a display string","items":{"$ref":"#/components/schemas/ValueMapping"},"type":"array"},"max":{"description":"The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"min":{"description":"The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.","type":"number"},"noValue":{"description":"Alternative to empty string","type":"string"},"path":{"description":"An explicit path to the field in the datasource. When the frame meta includes a path,\nThis will default to ` + "`" + `${frame.meta.path}/${field.name}\n\nWhen defined, this value can be used as an identifier within the datasource scope, and\nmay be used to update the results","type":"string"},"thresholds":{"$ref":"#/components/schemas/ThresholdsConfig","description":"Map numeric values to states"},"unit":{"description":"Unit a field should use. The unit you select is applied to all fields except time.\nYou can use the units ID availables in Grafana or a custom unit.\nAvailable units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts\nAs custom unit, you can use the following formats:\n` + "`" + `suffix:\u003csuffix\u003e` + "`" + ` for custom unit that should go after value.\n` + "`" + `prefix:\u003cprefix\u003e` + "`" + ` for custom unit that should go before value.\n` + "`" + `time:\u003cformat\u003e` + "`" + ` For custom date time formats type for example ` + "`" + `time:YYYY-MM-DD` + "`" + `.\n` + "`" + `si:\u003cbase scale\u003e\u003cunit characters\u003e` + "`" + ` for custom SI units. For example: ` + "`" + `si: mF` + "`" + `. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.\n` + "`" + `count:\u003cunit\u003e` + "`" + ` for a custom count unit.\n` + "`" + `currency:\u003cunit\u003e` + "`" + ` for custom a currency unit.","type":"string"},"writeable":{"description":"True if data source can write a value to the path. Auth/authz are supported separately","type":"boolean"}},"type":"object"},"FieldConfigSource":{"additionalProperties":false,"description":"The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.\nEach column within this structure is called a field. A field can represent a single time series or table column.\nField options allow you to change how the data is displayed in your visualizations.","properties":{"defaults":{"$ref":"#/components/schemas/FieldConfig","description":"Defaults are the options applied to all fields."},"overrides":{"description":"Overrides are the options applied to specific fields overriding the defaults.","items":{"additionalProperties":false,"properties":{"__systemRef":{"description":"Describes config override rules created when interacting with Grafana.","type":"string"},"matcher":{"$ref":"#/components/schemas/MatcherConfig"},"properties":{"items":{"$ref":"#/components/schemas/DynamicConfigValue"},"type":"array"}},"required":["matcher","properties"],"type":"object"},"type":"array"}},"required":["defaults","overrides"],"type":"object"},"FilterOrigin":{"const":"dashboard","description":"Determine the origin of the adhoc variable filter","type":"string"},"GridLayoutItemKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayoutItem","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutItemSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutItemSpec":{"additionalProperties":false,"properties":{"element":{"$ref":"#/components/schemas/ElementReference","description":"reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference"},"height":{"type":"integer"},"repeat":{"$ref":"#/components/schemas/RepeatOptions"},"width":{"type":"integer"},"x":{"type":"integer"},"y":{"type":"integer"}},"required":["x","y","width","height","element"],"type":"object"},"GridLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"GridLayout","type":"string"},"spec":{"$ref":"#/components/schemas/GridLayoutSpec"}},"required":["kind","spec"],"type":"object"},"GridLayoutSpec":{"additionalProperties":false,"properties":{"items":{"items":{"$ref":"#/components/schemas/GridLayoutItemKind"},"type":"array"}},"required":["items"],"type":"object"},"GroupByVariableKind":{"additionalProperties":false,"description":"Group variable kind","properties":{"datasource":{"additionalProperties":false,"properties":{"name":{"type":"string"}},"type":"object"},"group":{"type":"string"},"kind":{"const":"GroupByVariable","type":"string"},"spec":{"$ref":"#/components/schemas/GroupByVariableSpec"}},"required":["kind","group","spec"],"type":"object"},"GroupByVariableSpec":{"additionalProperties":false,"description":"GroupBy variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"defaultValue":{"$ref":"#/components/schemas/VariableOption"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","options","multi","hide","skipUrlSync"],"type":"object"},"HttpRequestMethod":{"enum":["GET","PUT","POST","DELETE","PATCH"],"type":"string"},"InfinityOptions":{"additionalProperties":false,"properties":{"body":{"type":"string"},"datasourceUid":{"type":"string"},"headers":{"items":{"items":{"type":"string"},"type":"array"},"type":"array"},"method":{"$ref":"#/components/schemas/HttpRequestMethod"},"queryParams":{"description":"These are 2D arrays of strings, each representing a key-value pair\nWe are defining them this way because we can't generate a go struct that\nthat would have exactly two strings in each sub-array","items":{"items":{"type":"string"},"type":"array"},"type":"array"},"url":{"type":"string"}},"required":["method","url","datasourceUid"],"type":"object"},"IntervalVariableKind":{"additionalProperties":false,"description":"Interval variable kind","properties":{"kind":{"const":"IntervalVariable","type":"string"},"spec":{"$ref":"#/components/schemas/IntervalVariableSpec"}},"required":["kind","spec"],"type":"object"},"IntervalVariableSpec":{"additionalProperties":false,"description":"Interval variable specification","properties":{"auto":{"default":false,"type":"boolean"},"auto_count":{"default":0,"type":"integer"},"auto_min":{"default":"","type":"string"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"query":{"default":"","type":"string"},"refresh":{"const":"onTimeRangeChanged","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","query","current","options","auto","auto_min","auto_count","refresh","hide","skipUrlSync"],"type":"object"},"LibraryPanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"LibraryPanel","type":"string"},"spec":{"$ref":"#/components/schemas/LibraryPanelKindSpec"}},"required":["kind","spec"],"type":"object"},"LibraryPanelKindSpec":{"additionalProperties":false,"properties":{"id":{"description":"Panel ID for the library panel in the dashboard","type":"number"},"libraryPanel":{"$ref":"#/components/schemas/LibraryPanelRef"},"title":{"description":"Title for the library panel in the dashboard","type":"string"}},"required":["id","title","libraryPanel"],"type":"object"},"LibraryPanelRef":{"additionalProperties":false,"description":"A library panel is a reusable panel that you can use in any dashboard.\nWhen you make a change to a library panel, that change propagates to all instances of where the panel is used.\nLibrary panels streamline reuse of panels across multiple dashboards.","properties":{"name":{"description":"Library panel name","type":"string"},"uid":{"description":"Library panel uid","type":"string"}},"required":["name","uid"],"type":"object"},"MappingType":{"description":"Supported value mapping types\n` + "`" + `value` + "`" + `: Maps text values to a color or different display text and color. For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.\n` + "`" + `range` + "`" + `: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.\n` + "`" + `regex` + "`" + `: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.\n` + "`" + `special` + "`" + `: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.","enum":["value","range","regex","special"],"type":"string"},"MatcherConfig":{"additionalProperties":false,"description":"Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.\nIt comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.","properties":{"id":{"default":"","description":"The matcher id. This is used to find the matcher implementation from registry.","type":"string"},"options":{"additionalProperties":{},"description":"The matcher options. This is specific to the matcher implementation.","type":"object"}},"required":["id"],"type":"object"},"MetricFindValue":{"additionalProperties":false,"description":"Define the MetricFindValue type","properties":{"expandable":{"type":"boolean"},"group":{"type":"string"},"text":{"type":"string"},"value":{"oneOf":[{"type":"string"},{"type":"number"}]}},"required":["text"],"type":"object"},"PanelKind":{"additionalProperties":false,"properties":{"kind":{"const":"Panel","type":"string"},"spec":{"$ref":"#/components/schemas/PanelSpec"}},"required":["kind","spec"],"type":"object"},"PanelQueryKind":{"additionalProperties":false,"properties":{"kind":{"const":"PanelQuery","type":"string"},"spec":{"$ref":"#/components/schemas/PanelQuerySpec"}},"required":["kind","spec"],"type":"object"},"PanelQuerySpec":{"additionalProperties":false,"properties":{"hidden":{"type":"boolean"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refId":{"default":"A","type":"string"}},"required":["query","refId","hidden"],"type":"object"},"PanelSpec":{"additionalProperties":false,"properties":{"data":{"$ref":"#/components/schemas/QueryGroupKind"},"description":{"type":"string"},"id":{"type":"number"},"links":{"items":{"$ref":"#/components/schemas/DataLink"},"type":"array"},"title":{"type":"string"},"transparent":{"type":"boolean"},"vizConfig":{"$ref":"#/components/schemas/VizConfigKind"}},"required":["id","title","description","links","data","vizConfig"],"type":"object"},"QueryGroupKind":{"additionalProperties":false,"properties":{"kind":{"const":"QueryGroup","type":"string"},"spec":{"$ref":"#/components/schemas/QueryGroupSpec"}},"required":["kind","spec"],"type":"object"},"QueryGroupSpec":{"additionalProperties":false,"properties":{"queries":{"items":{"$ref":"#/components/schemas/PanelQueryKind"},"type":"array"},"queryOptions":{"$ref":"#/components/schemas/QueryOptionsSpec"},"transformations":{"items":{"$ref":"#/components/schemas/TransformationKind"},"type":"array"}},"required":["queries","transformations","queryOptions"],"type":"object"},"QueryOptionsSpec":{"additionalProperties":false,"properties":{"cacheTimeout":{"type":"string"},"hideTimeOverride":{"type":"boolean"},"interval":{"type":"string"},"maxDataPoints":{"type":"integer"},"queryCachingTTL":{"type":"integer"},"timeCompare":{"type":"string"},"timeFrom":{"type":"string"},"timeShift":{"type":"string"}},"type":"object"},"QueryVariableKind":{"additionalProperties":false,"description":"Query variable kind","properties":{"kind":{"const":"QueryVariable","type":"string"},"spec":{"$ref":"#/components/schemas/QueryVariableSpec"}},"required":["kind","spec"],"type":"object"},"QueryVariableSpec":{"additionalProperties":false,"description":"Query variable specification","properties":{"allValue":{"type":"string"},"allowCustomValue":{"default":true,"type":"boolean"},"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"definition":{"type":"string"},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"includeAll":{"default":false,"type":"boolean"},"label":{"type":"string"},"multi":{"default":false,"type":"boolean"},"name":{"default":"","type":"string"},"options":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"placeholder":{"type":"string"},"query":{"$ref":"#/components/schemas/DataQueryKind"},"refresh":{"$ref":"#/components/schemas/VariableRefresh","default":"never"},"regex":{"default":"","type":"string"},"regexApplyTo":{"$ref":"#/components/schemas/VariableRegexApplyTo","default":"value"},"skipUrlSync":{"default":false,"type":"boolean"},"sort":{"$ref":"#/components/schemas/VariableSort"},"staticOptions":{"items":{"$ref":"#/components/schemas/VariableOption"},"type":"array"},"staticOptionsOrder":{"enum":["before","after","sorted"],"type":"string"}},"required":["name","current","hide","refresh","skipUrlSync","query","regex","sort","options","multi","includeAll","allowCustomValue"],"type":"object"},"RangeMap":{"additionalProperties":false,"description":"Maps numerical ranges to a display text and color.\nFor example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.","properties":{"options":{"additionalProperties":false,"description":"Range to match against and the result to apply when the value is within the range","properties":{"from":{"description":"Min value of the range. It can be null which means -Infinity","type":"number"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value is within the range"},"to":{"description":"Max value of the range. It can be null which means +Infinity","type":"number"}},"required":["from","to","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RegexMap":{"additionalProperties":false,"description":"Maps regular expressions to replacement text and a color.\nFor example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.","properties":{"options":{"additionalProperties":false,"description":"Regular expression to match against and the result to apply when the value matches the regex","properties":{"pattern":{"description":"Regular expression to match against","type":"string"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the regex"}},"required":["pattern","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"RepeatMode":{"const":"variable","description":"other repeat modes will be added in the future: label, frame","type":"string"},"RepeatOptions":{"additionalProperties":false,"properties":{"direction":{"enum":["h","v"],"type":"string"},"maxPerRow":{"type":"integer"},"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"RowsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowKind":{"additionalProperties":false,"properties":{"kind":{"const":"RowsLayoutRow","type":"string"},"spec":{"$ref":"#/components/schemas/RowsLayoutRowSpec"}},"required":["kind","spec"],"type":"object"},"RowsLayoutRowSpec":{"additionalProperties":false,"properties":{"collapse":{"type":"boolean"},"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"fillScreen":{"type":"boolean"},"hideHeader":{"type":"boolean"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/RowRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"RowsLayoutSpec":{"additionalProperties":false,"properties":{"rows":{"items":{"$ref":"#/components/schemas/RowsLayoutRowKind"},"type":"array"}},"required":["rows"],"type":"object"},"SpecialValueMap":{"additionalProperties":false,"description":"Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color.\nSee SpecialValueMatch to see the list of special values.\nFor example, you can configure a special value mapping so that null values appear as N/A.","properties":{"options":{"additionalProperties":false,"properties":{"match":{"$ref":"#/components/schemas/SpecialValueMatch","description":"Special value to match against"},"result":{"$ref":"#/components/schemas/ValueMappingResult","description":"Config to apply when the value matches the special value"}},"required":["match","result"],"type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"SpecialValueMatch":{"description":"Special value types supported by the ` + "`" + `SpecialValueMap` + "`" + `","enum":["true","false","null","nan","null+nan","empty"],"type":"string"},"SwitchVariableKind":{"additionalProperties":false,"properties":{"kind":{"const":"SwitchVariable","type":"string"},"spec":{"$ref":"#/components/schemas/SwitchVariableSpec"}},"required":["kind","spec"],"type":"object"},"SwitchVariableSpec":{"additionalProperties":false,"properties":{"current":{"default":"false","type":"string"},"description":{"type":"string"},"disabledValue":{"default":"false","type":"string"},"enabledValue":{"default":"true","type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","enabledValue","disabledValue","hide","skipUrlSync"],"type":"object"},"TabRepeatOptions":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/RepeatMode"},"value":{"type":"string"}},"required":["mode","value"],"type":"object"},"TabsLayoutKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayout","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutSpec":{"additionalProperties":false,"properties":{"tabs":{"items":{"$ref":"#/components/schemas/TabsLayoutTabKind"},"type":"array"}},"required":["tabs"],"type":"object"},"TabsLayoutTabKind":{"additionalProperties":false,"properties":{"kind":{"const":"TabsLayoutTab","type":"string"},"spec":{"$ref":"#/components/schemas/TabsLayoutTabSpec"}},"required":["kind","spec"],"type":"object"},"TabsLayoutTabSpec":{"additionalProperties":false,"properties":{"conditionalRendering":{"$ref":"#/components/schemas/ConditionalRenderingGroupKind"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"repeat":{"$ref":"#/components/schemas/TabRepeatOptions"},"title":{"type":"string"}},"required":["layout"],"type":"object"},"TextVariableKind":{"additionalProperties":false,"description":"Text variable kind","properties":{"kind":{"const":"TextVariable","type":"string"},"spec":{"$ref":"#/components/schemas/TextVariableSpec"}},"required":["kind","spec"],"type":"object"},"TextVariableSpec":{"additionalProperties":false,"description":"Text variable specification","properties":{"current":{"$ref":"#/components/schemas/VariableOption","default":{"text":"","value":""}},"description":{"type":"string"},"hide":{"$ref":"#/components/schemas/VariableHide","default":"dontHide"},"label":{"type":"string"},"name":{"default":"","type":"string"},"query":{"default":"","type":"string"},"skipUrlSync":{"default":false,"type":"boolean"}},"required":["name","current","query","hide","skipUrlSync"],"type":"object"},"Threshold":{"additionalProperties":false,"properties":{"color":{"type":"string"},"value":{"description":"Value null means -Infinity","type":"number"}},"required":["value","color"],"type":"object"},"ThresholdsConfig":{"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/ThresholdsMode"},"steps":{"items":{"$ref":"#/components/schemas/Threshold"},"type":"array"}},"required":["mode","steps"],"type":"object"},"ThresholdsMode":{"enum":["absolute","percentage"],"type":"string"},"TimeRangeOption":{"additionalProperties":false,"properties":{"display":{"default":"Last 6 hours","type":"string"},"from":{"default":"now-6h","type":"string"},"to":{"default":"now","type":"string"}},"required":["display","from","to"],"type":"object"},"TimeSettingsSpec":{"additionalProperties":false,"description":"Time configuration\nIt defines the default time config for the time picker, the refresh picker for the specific dashboard.","properties":{"autoRefresh":{"default":"","description":"Refresh rate of dashboard. Represented via interval string, e.g. \"5s\", \"1m\", \"1h\", \"1d\".\nv1: refresh","type":"string"},"autoRefreshIntervals":{"default":["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"],"description":"Interval options available in the refresh picker dropdown.\nv1: timepicker.refresh_intervals","items":{"type":"string"},"type":"array"},"fiscalYearStartMonth":{"default":0,"description":"The month that the fiscal year starts on. 0 = January, 11 = December","type":"integer"},"from":{"default":"now-6h","description":"Start time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"hideTimepicker":{"default":false,"description":"Whether timepicker is visible or not.\nv1: timepicker.hidden","type":"boolean"},"nowDelay":{"description":"Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values.\nv1: timepicker.nowDelay","type":"string"},"quickRanges":{"description":"Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.\nv1: timepicker.quick_ranges , not exposed in the UI","items":{"$ref":"#/components/schemas/TimeRangeOption"},"type":"array"},"timezone":{"default":"browser","description":"Timezone of dashboard. Accepted values are IANA TZDB zone ID or \"browser\" or \"utc\".","type":"string"},"to":{"default":"now","description":"End time range for dashboard.\nAccepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".","type":"string"},"weekStart":{"description":"Day when the week starts. Expressed by the name of the day in lowercase, e.g. \"monday\".","enum":["saturday","monday","sunday"],"type":"string"}},"required":["from","to","autoRefresh","autoRefreshIntervals","hideTimepicker","fiscalYearStartMonth"],"type":"object"},"TransformationKind":{"additionalProperties":false,"properties":{"kind":{"description":"The kind of a TransformationKind is the transformation ID","type":"string"},"spec":{"$ref":"#/components/schemas/DataTransformerConfig"}},"required":["kind","spec"],"type":"object"},"ValueMap":{"additionalProperties":false,"description":"Maps text values to a color or different display text and color.\nFor example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.","properties":{"options":{"additionalProperties":{"$ref":"#/components/schemas/ValueMappingResult"},"description":"Map with \u003cvalue_to_match\u003e: ValueMappingResult. For example: { \"10\": { text: \"Perfection!\", color: \"green\" } }","type":"object"},"type":{"$ref":"#/components/schemas/MappingType"}},"required":["type","options"],"type":"object"},"ValueMapping":{"oneOf":[{"$ref":"#/components/schemas/ValueMap"},{"$ref":"#/components/schemas/RangeMap"},{"$ref":"#/components/schemas/RegexMap"},{"$ref":"#/components/schemas/SpecialValueMap"}]},"ValueMappingResult":{"additionalProperties":false,"description":"Result used as replacement with text and color when the value matches","properties":{"color":{"description":"Text to use when the value matches","type":"string"},"icon":{"description":"Icon to display when the value matches. Only specific visualizations.","type":"string"},"index":{"description":"Position in the mapping array. Only used internally.","type":"integer"},"text":{"description":"Text to display when the value matches","type":"string"}},"type":"object"},"VariableHide":{"description":"Determine if the variable shows on dashboard\nAccepted values are ` + "`" + `dontHide` + "`" + ` (show label and value), ` + "`" + `hideLabel` + "`" + ` (show value only), ` + "`" + `hideVariable` + "`" + ` (show nothing), ` + "`" + `inControlsMenu` + "`" + ` (show in a drop-down menu).","enum":["dontHide","hideLabel","hideVariable","inControlsMenu"],"type":"string"},"VariableKind":{"oneOf":[{"$ref":"#/components/schemas/QueryVariableKind"},{"$ref":"#/components/schemas/TextVariableKind"},{"$ref":"#/components/schemas/ConstantVariableKind"},{"$ref":"#/components/schemas/DatasourceVariableKind"},{"$ref":"#/components/schemas/IntervalVariableKind"},{"$ref":"#/components/schemas/CustomVariableKind"},{"$ref":"#/components/schemas/GroupByVariableKind"},{"$ref":"#/components/schemas/AdhocVariableKind"},{"$ref":"#/components/schemas/SwitchVariableKind"}]},"VariableOption":{"additionalProperties":false,"description":"Variable option specification","properties":{"selected":{"description":"Whether the option is selected or not","type":"boolean"},"text":{"description":"Text to be displayed for the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]},"value":{"description":"Value of the option","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]}},"required":["text","value"],"type":"object"},"VariableRefresh":{"description":"Options to config when to refresh a variable\n` + "`" + `never` + "`" + `: Never refresh the variable\n` + "`" + `onDashboardLoad` + "`" + `: Queries the data source every time the dashboard loads.\n` + "`" + `onTimeRangeChanged` + "`" + `: Queries the data source when the dashboard time range changes.","enum":["never","onDashboardLoad","onTimeRangeChanged"],"type":"string"},"VariableRegexApplyTo":{"description":"Determine whether regex applies to variable value or display text\nAccepted values are ` + "`" + `value` + "`" + ` (apply to value used in queries) or ` + "`" + `text` + "`" + ` (apply to display text shown to users)","enum":["value","text"],"type":"string"},"VariableSort":{"description":"Sort variable options\nAccepted values are:\n` + "`" + `disabled` + "`" + `: No sorting\n` + "`" + `alphabeticalAsc` + "`" + `: Alphabetical ASC\n` + "`" + `alphabeticalDesc` + "`" + `: Alphabetical DESC\n` + "`" + `numericalAsc` + "`" + `: Numerical ASC\n` + "`" + `numericalDesc` + "`" + `: Numerical DESC\n` + "`" + `alphabeticalCaseInsensitiveAsc` + "`" + `: Alphabetical Case Insensitive ASC\n` + "`" + `alphabeticalCaseInsensitiveDesc` + "`" + `: Alphabetical Case Insensitive DESC\n` + "`" + `naturalAsc` + "`" + `: Natural ASC\n` + "`" + `naturalDesc` + "`" + `: Natural DESC\nVariableSort enum with default value","enum":["disabled","alphabeticalAsc","alphabeticalDesc","numericalAsc","numericalDesc","alphabeticalCaseInsensitiveAsc","alphabeticalCaseInsensitiveDesc","naturalAsc","naturalDesc"],"type":"string"},"VizConfigKind":{"additionalProperties":false,"properties":{"group":{"description":"The group is the plugin ID","type":"string"},"kind":{"const":"VizConfig","type":"string"},"spec":{"$ref":"#/components/schemas/VizConfigSpec"},"version":{"type":"string"}},"required":["kind","group","version","spec"],"type":"object"},"VizConfigSpec":{"additionalProperties":false,"description":"--- Kinds ---","properties":{"fieldConfig":{"$ref":"#/components/schemas/FieldConfigSource"},"options":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"}},"required":["options","fieldConfig"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"annotations":{"items":{"$ref":"#/components/schemas/AnnotationQueryKind"},"type":"array"},"cursorSync":{"$ref":"#/components/schemas/DashboardCursorSync","default":"Off","description":"Configuration of dashboard cursor sync behavior.\n\"Off\" for no shared crosshair or tooltip (default).\n\"Crosshair\" for shared crosshair.\n\"Tooltip\" for shared crosshair AND shared tooltip."},"description":{"description":"Description of dashboard.","type":"string"},"editable":{"default":true,"description":"Whether a dashboard is editable or not.","type":"boolean"},"elements":{"additionalProperties":{"$ref":"#/components/schemas/Element"},"type":"object"},"layout":{"oneOf":[{"$ref":"#/components/schemas/GridLayoutKind"},{"$ref":"#/components/schemas/RowsLayoutKind"},{"$ref":"#/components/schemas/AutoGridLayoutKind"},{"$ref":"#/components/schemas/TabsLayoutKind"}]},"links":{"description":"Links with references to other dashboards or external websites.","items":{"$ref":"#/components/schemas/DashboardLink"},"type":"array"},"liveNow":{"description":"When set to true, the dashboard will redraw panels at an interval matching the pixel width.\nThis will keep data \"moving left\" regardless of the query refresh rate. This setting helps\navoid dashboards presenting stale live data.","type":"boolean"},"preload":{"default":false,"description":"When set to true, the dashboard will load all panels in the dashboard when it's loaded.","type":"boolean"},"revision":{"description":"Plugins only. The version of the dashboard installed together with the plugin.\nThis is used to determine if the dashboard should be updated when the plugin is updated.","type":"integer"},"tags":{"description":"Tags associated with dashboard.","items":{"type":"string"},"type":"array"},"timeSettings":{"$ref":"#/components/schemas/TimeSettingsSpec"},"title":{"description":"Title of dashboard.","type":"string"},"variables":{"description":"Configured template variables.","items":{"$ref":"#/components/schemas/VariableKind"},"type":"array"}},"required":["annotations","cursorSync","elements","layout","links","preload","tags","timeSettings","title","variables"],"type":"object"},"status":{"additionalProperties":false,"properties":{"conversion":{"$ref":"#/components/schemas/ConversionStatus","description":"Optional conversion status."}},"type":"object"}}`) versionSchemaDashboardv2beta1 app.VersionSchema _ = json.Unmarshal(rawSchemaDashboardv2beta1, &versionSchemaDashboardv2beta1) ) diff --git a/apps/dashboard/pkg/migration/README.md b/apps/dashboard/pkg/migration/README.md index ab938e31f66..6fd2069cce9 100644 --- a/apps/dashboard/pkg/migration/README.md +++ b/apps/dashboard/pkg/migration/README.md @@ -53,6 +53,7 @@ v0alpha1 (Legacy JSON) → v1beta1 (Migrated JSON) → v2alpha1/v2beta1 (Structu - Transforms JSON dashboards to structured dashboard format - v2 schema is the stable, typed schema with proper type definitions - Handles modern dashboard features and Kubernetes-native storage +- Preserves Angular panel migration data for frontend processing (see [Angular Panel Migrations](#angular-panel-migrations)) - See [V2 to V1 Layout Conversion](./conversion/v2_to_v1_layout_conversion.md) for details on how V2 layouts are converted back to V1 panel arrays #### v2 to v0/v1 Conversion: @@ -61,6 +62,76 @@ v0alpha1 (Legacy JSON) → v1beta1 (Migrated JSON) → v2alpha1/v2beta1 (Structu - v0alpha1 and v1beta1 share the same spec structure (only API version differs) - Enables backward compatibility when storing v2 dashboards in legacy format +### Angular Panel Migrations + +When converting dashboards from v0/v1 to v2, panels with Angular types require special handling. The `autoMigrateFrom` field is used in v0 and v1 to indicate the panel was migrated from a deprecated plugin type, and the target plugin contains migration logic to transform the original panel's options and field configurations. + +Panel plugins define their own migration logic via `plugin.onPanelTypeChanged()`. This migration runs in the frontend when a panel type changes, transforming old options/fieldConfig to the new format. Examples: +- `singlestat.format: "short"` → `stat.fieldConfig.defaults.unit: "short"` +- `graph.legend.show: true` → `timeseries.options.legend.showLegend: true` + +The v2 schema doesn't include `autoMigrateFrom` as a typed field, so we need a mechanism to preserve the original panel data for the frontend to run these plugin migrations. + +#### `__angularMigration` Temporary Data + +The backend v1 → v2 conversion preserves the original panel data in a temporary field within `vizConfig.spec.options`. This works for **any** Angular panel, not just specific panel types: + +```json +{ + "vizConfig": { + "kind": "stat", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalPanel": { + "type": "singlestat", + "format": "short", + "colorBackground": true, + "sparkline": { "show": true }, + "fieldConfig": { ... }, + "options": { ... } + } + } + } + } + } +} +``` + +#### How It Works + +1. **Backend (v1 → v2):** The conversion detects panels that need Angular migration in two ways: + - If `autoMigrateFrom` is already set on the panel (from v0 → v1 migration) - panel type already converted + - If the panel type is a known Angular panel type (fallback for dashboards stored directly as v1 without v0 → v1 migration) + + In the second case, the conversion also transforms the panel type (e.g., `singlestat` → `stat`) and sets `autoMigrateFrom`. This replicates the same logic as the v0 → v1 migration. + + The entire original panel is stored under `options.__angularMigration` for the frontend to run plugin-specific migrations. + +2. **Frontend (v2 load):** When building a `VizPanel` from v2 data: + - Extracts `__angularMigration` from options + - Removes it from the options object (not persisted) + - Attaches a custom migration handler via `_UNSAFE_customMigrationHandler` + +3. **Plugin load (VizPanel activation):** When the plugin loads, the migration handler calls `plugin.onPanelTypeChanged()` with the original panel data, allowing the plugin's own migration code to run + +#### Key Points + +- Works for **any** panel with `autoMigrateFrom`, not limited to specific panel types +- Each plugin defines its own migration logic - the backend just preserves the data +- The `originalPanel` contains the complete panel data to ensure no information is lost +- Migration data is removed from options after loaded in frontend +- The 0v → v1 and v1 → v2 conversions automatically detects these Angular panel types if `autoMigrateFrom` is not set. + +#### Implementation Files + +| File | Purpose | +|------|---------| +| `apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1.go` | Injects `__angularMigration` during v1 → v2 | +| `public/app/features/dashboard-scene/serialization/layoutSerializers/utils.ts` | Extracts and consumes `__angularMigration` | +| `public/app/features/dashboard-scene/serialization/angularMigration.ts` | Creates migration handler for v2 path | + ## Conversion Matrix The system supports conversions between all dashboard API versions: diff --git a/apps/dashboard/pkg/migration/conversion/conversion.go b/apps/dashboard/pkg/migration/conversion/conversion.go index d0f90e1ba98..ad65dc84c85 100644 --- a/apps/dashboard/pkg/migration/conversion/conversion.go +++ b/apps/dashboard/pkg/migration/conversion/conversion.go @@ -12,13 +12,6 @@ import ( ) func RegisterConversions(s *runtime.Scheme, dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) error { - // Wrap the provider once with 10s caching for all conversions. - // This prevents repeated DB queries across multiple conversion calls while allowing - // the cache to refresh periodically, making it suitable for long-lived singleton usage. - dsIndexProvider = schemaversion.WrapIndexProviderWithCache(dsIndexProvider) - // Wrap library element provider with caching as well - leIndexProvider = schemaversion.WrapLibraryElementProviderWithCache(leIndexProvider) - // v0 conversions if err := s.AddConversionFunc((*dashv0.Dashboard)(nil), (*dashv1.Dashboard)(nil), withConversionMetrics(dashv0.APIVERSION, dashv1.APIVERSION, func(a, b interface{}, scope conversion.Scope) error { @@ -62,13 +55,13 @@ func RegisterConversions(s *runtime.Scheme, dsIndexProvider schemaversion.DataSo // v2alpha1 conversions if err := s.AddConversionFunc((*dashv2alpha1.Dashboard)(nil), (*dashv0.Dashboard)(nil), withConversionMetrics(dashv2alpha1.APIVERSION, dashv0.APIVERSION, func(a, b interface{}, scope conversion.Scope) error { - return Convert_V2alpha1_to_V0(a.(*dashv2alpha1.Dashboard), b.(*dashv0.Dashboard), scope, dsIndexProvider) + return Convert_V2alpha1_to_V0(a.(*dashv2alpha1.Dashboard), b.(*dashv0.Dashboard), scope) })); err != nil { return err } if err := s.AddConversionFunc((*dashv2alpha1.Dashboard)(nil), (*dashv1.Dashboard)(nil), withConversionMetrics(dashv2alpha1.APIVERSION, dashv1.APIVERSION, func(a, b interface{}, scope conversion.Scope) error { - return Convert_V2alpha1_to_V1beta1(a.(*dashv2alpha1.Dashboard), b.(*dashv1.Dashboard), scope, dsIndexProvider) + return Convert_V2alpha1_to_V1beta1(a.(*dashv2alpha1.Dashboard), b.(*dashv1.Dashboard), scope) })); err != nil { return err } diff --git a/apps/dashboard/pkg/migration/conversion/conversion_cache_test.go b/apps/dashboard/pkg/migration/conversion/conversion_cache_test.go new file mode 100644 index 00000000000..3e54d9682fd --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/conversion_cache_test.go @@ -0,0 +1,454 @@ +package conversion + +import ( + "context" + "sync/atomic" + "testing" + "time" + + dashv0 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1" + dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1" + dashv2alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1" + dashv2beta1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2beta1" + "github.com/grafana/grafana/apps/dashboard/pkg/migration" + "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion" + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// countingDataSourceProvider tracks how many times Index() is called +type countingDataSourceProvider struct { + datasources []schemaversion.DataSourceInfo + callCount atomic.Int64 +} + +func newCountingDataSourceProvider(datasources []schemaversion.DataSourceInfo) *countingDataSourceProvider { + return &countingDataSourceProvider{ + datasources: datasources, + } +} + +func (p *countingDataSourceProvider) Index(_ context.Context) *schemaversion.DatasourceIndex { + p.callCount.Add(1) + return schemaversion.NewDatasourceIndex(p.datasources) +} + +func (p *countingDataSourceProvider) getCallCount() int64 { + return p.callCount.Load() +} + +// countingLibraryElementProvider tracks how many times GetLibraryElementInfo() is called +type countingLibraryElementProvider struct { + elements []schemaversion.LibraryElementInfo + callCount atomic.Int64 +} + +func newCountingLibraryElementProvider(elements []schemaversion.LibraryElementInfo) *countingLibraryElementProvider { + return &countingLibraryElementProvider{ + elements: elements, + } +} + +func (p *countingLibraryElementProvider) GetLibraryElementInfo(_ context.Context) []schemaversion.LibraryElementInfo { + p.callCount.Add(1) + return p.elements +} + +func (p *countingLibraryElementProvider) getCallCount() int64 { + return p.callCount.Load() +} + +// createTestV0Dashboard creates a minimal v0 dashboard for testing +// The dashboard has a datasource with UID only (no type) to force provider lookup +// and includes library panels to test library element provider caching +func createTestV0Dashboard(namespace, title string) *dashv0.Dashboard { + return &dashv0.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + Namespace: namespace, + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": title, + "schemaVersion": schemaversion.LATEST_VERSION, + // Variables with datasource reference that requires lookup + "templating": map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{ + "name": "query_var", + "type": "query", + "query": "label_values(up, job)", + // Datasource with UID only - type needs to be looked up + "datasource": map[string]interface{}{ + "uid": "ds1", + // type is intentionally omitted to trigger provider lookup + }, + }, + }, + }, + "panels": []interface{}{ + map[string]interface{}{ + "id": 1, + "title": "Test Panel", + "type": "timeseries", + "targets": []interface{}{ + map[string]interface{}{ + // Datasource with UID only - type needs to be looked up + "datasource": map[string]interface{}{ + "uid": "ds1", + }, + }, + }, + }, + // Library panel reference - triggers library element provider lookup + map[string]interface{}{ + "id": 2, + "title": "Library Panel with Horizontal Repeat", + "type": "library-panel-ref", + "gridPos": map[string]interface{}{ + "h": 8, + "w": 12, + "x": 0, + "y": 8, + }, + "libraryPanel": map[string]interface{}{ + "uid": "lib-panel-repeat-h", + "name": "Library Panel with Horizontal Repeat", + }, + }, + // Another library panel reference + map[string]interface{}{ + "id": 3, + "title": "Library Panel without Repeat", + "type": "library-panel-ref", + "gridPos": map[string]interface{}{ + "h": 3, + "w": 6, + "x": 0, + "y": 16, + }, + "libraryPanel": map[string]interface{}{ + "uid": "lib-panel-no-repeat", + "name": "Library Panel without Repeat", + }, + }, + }, + }, + }, + } +} + +// createTestV1Dashboard creates a minimal v1beta1 dashboard for testing +// The dashboard has a datasource with UID only (no type) to force provider lookup +// and includes library panels to test library element provider caching +func createTestV1Dashboard(namespace, title string) *dashv1.Dashboard { + return &dashv1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-dashboard", + Namespace: namespace, + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": title, + "schemaVersion": schemaversion.LATEST_VERSION, + // Variables with datasource reference that requires lookup + "templating": map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{ + "name": "query_var", + "type": "query", + "query": "label_values(up, job)", + // Datasource with UID only - type needs to be looked up + "datasource": map[string]interface{}{ + "uid": "ds1", + // type is intentionally omitted to trigger provider lookup + }, + }, + }, + }, + "panels": []interface{}{ + map[string]interface{}{ + "id": 1, + "title": "Test Panel", + "type": "timeseries", + "targets": []interface{}{ + map[string]interface{}{ + // Datasource with UID only - type needs to be looked up + "datasource": map[string]interface{}{ + "uid": "ds1", + }, + }, + }, + }, + // Library panel reference - triggers library element provider lookup + map[string]interface{}{ + "id": 2, + "title": "Library Panel with Vertical Repeat", + "type": "library-panel-ref", + "gridPos": map[string]interface{}{ + "h": 4, + "w": 6, + "x": 0, + "y": 8, + }, + "libraryPanel": map[string]interface{}{ + "uid": "lib-panel-repeat-v", + "name": "Library Panel with Vertical Repeat", + }, + }, + // Another library panel reference + map[string]interface{}{ + "id": 3, + "title": "Library Panel without Repeat", + "type": "library-panel-ref", + "gridPos": map[string]interface{}{ + "h": 3, + "w": 6, + "x": 6, + "y": 8, + }, + "libraryPanel": map[string]interface{}{ + "uid": "lib-panel-no-repeat", + "name": "Library Panel without Repeat", + }, + }, + }, + }, + }, + } +} + +// TestConversionCaching_V0_to_V2alpha1 verifies caching works when converting V0 to V2alpha1 +func TestConversionCaching_V0_to_V2alpha1(t *testing.T) { + datasources := []schemaversion.DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + elements := []schemaversion.LibraryElementInfo{ + {UID: "lib-panel-repeat-h", Name: "Library Panel with Horizontal Repeat", Type: "timeseries"}, + {UID: "lib-panel-no-repeat", Name: "Library Panel without Repeat", Type: "graph"}, + } + + underlyingDS := newCountingDataSourceProvider(datasources) + underlyingLE := newCountingLibraryElementProvider(elements) + + cachedDS := schemaversion.WrapIndexProviderWithCache(underlyingDS, time.Minute) + cachedLE := schemaversion.WrapLibraryElementProviderWithCache(underlyingLE, time.Minute) + + migration.ResetForTesting() + migration.Initialize(cachedDS, cachedLE, migration.DefaultCacheTTL) + + // Convert multiple dashboards in the same namespace + numDashboards := 5 + namespace := "default" + + for i := 0; i < numDashboards; i++ { + source := createTestV0Dashboard(namespace, "Dashboard "+string(rune('A'+i))) + target := &dashv2alpha1.Dashboard{} + + err := Convert_V0_to_V2alpha1(source, target, nil, cachedDS, cachedLE) + require.NoError(t, err, "conversion %d should succeed", i) + require.NotNil(t, target.Spec) + } + + // With caching, the underlying datasource provider should only be called once per namespace + // The test dashboard has datasources without type that require lookup + assert.Equal(t, int64(1), underlyingDS.getCallCount(), + "datasource provider should be called only once for %d conversions in same namespace", numDashboards) + // Library element provider should also be called only once per namespace due to caching + assert.Equal(t, int64(1), underlyingLE.getCallCount(), + "library element provider should be called only once for %d conversions in same namespace", numDashboards) +} + +// TestConversionCaching_V0_to_V2beta1 verifies caching works when converting V0 to V2beta1 +func TestConversionCaching_V0_to_V2beta1(t *testing.T) { + datasources := []schemaversion.DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + elements := []schemaversion.LibraryElementInfo{ + {UID: "lib-panel-repeat-h", Name: "Library Panel with Horizontal Repeat", Type: "timeseries"}, + {UID: "lib-panel-no-repeat", Name: "Library Panel without Repeat", Type: "graph"}, + } + + underlyingDS := newCountingDataSourceProvider(datasources) + underlyingLE := newCountingLibraryElementProvider(elements) + + cachedDS := schemaversion.WrapIndexProviderWithCache(underlyingDS, time.Minute) + cachedLE := schemaversion.WrapLibraryElementProviderWithCache(underlyingLE, time.Minute) + + migration.ResetForTesting() + migration.Initialize(cachedDS, cachedLE, migration.DefaultCacheTTL) + + numDashboards := 5 + namespace := "default" + + for i := 0; i < numDashboards; i++ { + source := createTestV0Dashboard(namespace, "Dashboard "+string(rune('A'+i))) + target := &dashv2beta1.Dashboard{} + + err := Convert_V0_to_V2beta1(source, target, nil, cachedDS, cachedLE) + require.NoError(t, err, "conversion %d should succeed", i) + require.NotNil(t, target.Spec) + } + + assert.Equal(t, int64(1), underlyingDS.getCallCount(), + "datasource provider should be called only once for %d conversions in same namespace", numDashboards) + assert.Equal(t, int64(1), underlyingLE.getCallCount(), + "library element provider should be called only once for %d conversions in same namespace", numDashboards) +} + +// TestConversionCaching_V1beta1_to_V2alpha1 verifies caching works when converting V1beta1 to V2alpha1 +func TestConversionCaching_V1beta1_to_V2alpha1(t *testing.T) { + datasources := []schemaversion.DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + elements := []schemaversion.LibraryElementInfo{ + {UID: "lib-panel-repeat-v", Name: "Library Panel with Vertical Repeat", Type: "timeseries"}, + {UID: "lib-panel-no-repeat", Name: "Library Panel without Repeat", Type: "graph"}, + } + + underlyingDS := newCountingDataSourceProvider(datasources) + underlyingLE := newCountingLibraryElementProvider(elements) + + cachedDS := schemaversion.WrapIndexProviderWithCache(underlyingDS, time.Minute) + cachedLE := schemaversion.WrapLibraryElementProviderWithCache(underlyingLE, time.Minute) + + migration.ResetForTesting() + migration.Initialize(cachedDS, cachedLE, migration.DefaultCacheTTL) + + numDashboards := 5 + namespace := "default" + + for i := 0; i < numDashboards; i++ { + source := createTestV1Dashboard(namespace, "Dashboard "+string(rune('A'+i))) + target := &dashv2alpha1.Dashboard{} + + err := Convert_V1beta1_to_V2alpha1(source, target, nil, cachedDS, cachedLE) + require.NoError(t, err, "conversion %d should succeed", i) + require.NotNil(t, target.Spec) + } + + assert.Equal(t, int64(1), underlyingDS.getCallCount(), + "datasource provider should be called only once for %d conversions in same namespace", numDashboards) + assert.Equal(t, int64(1), underlyingLE.getCallCount(), + "library element provider should be called only once for %d conversions in same namespace", numDashboards) +} + +// TestConversionCaching_V1beta1_to_V2beta1 verifies caching works when converting V1beta1 to V2beta1 +func TestConversionCaching_V1beta1_to_V2beta1(t *testing.T) { + datasources := []schemaversion.DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + elements := []schemaversion.LibraryElementInfo{ + {UID: "lib-panel-repeat-v", Name: "Library Panel with Vertical Repeat", Type: "timeseries"}, + {UID: "lib-panel-no-repeat", Name: "Library Panel without Repeat", Type: "graph"}, + } + + underlyingDS := newCountingDataSourceProvider(datasources) + underlyingLE := newCountingLibraryElementProvider(elements) + + cachedDS := schemaversion.WrapIndexProviderWithCache(underlyingDS, time.Minute) + cachedLE := schemaversion.WrapLibraryElementProviderWithCache(underlyingLE, time.Minute) + + migration.ResetForTesting() + migration.Initialize(cachedDS, cachedLE, migration.DefaultCacheTTL) + + numDashboards := 5 + namespace := "default" + + for i := 0; i < numDashboards; i++ { + source := createTestV1Dashboard(namespace, "Dashboard "+string(rune('A'+i))) + target := &dashv2beta1.Dashboard{} + + err := Convert_V1beta1_to_V2beta1(source, target, nil, cachedDS, cachedLE) + require.NoError(t, err, "conversion %d should succeed", i) + require.NotNil(t, target.Spec) + } + + assert.Equal(t, int64(1), underlyingDS.getCallCount(), + "datasource provider should be called only once for %d conversions in same namespace", numDashboards) + assert.Equal(t, int64(1), underlyingLE.getCallCount(), + "library element provider should be called only once for %d conversions in same namespace", numDashboards) +} + +// TestConversionCaching_MultipleNamespaces verifies that different namespaces get separate cache entries +func TestConversionCaching_MultipleNamespaces(t *testing.T) { + datasources := []schemaversion.DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + elements := []schemaversion.LibraryElementInfo{ + {UID: "lib-panel-repeat-h", Name: "Library Panel with Horizontal Repeat", Type: "timeseries"}, + {UID: "lib-panel-no-repeat", Name: "Library Panel without Repeat", Type: "graph"}, + } + + underlyingDS := newCountingDataSourceProvider(datasources) + underlyingLE := newCountingLibraryElementProvider(elements) + + cachedDS := schemaversion.WrapIndexProviderWithCache(underlyingDS, time.Minute) + cachedLE := schemaversion.WrapLibraryElementProviderWithCache(underlyingLE, time.Minute) + + migration.ResetForTesting() + migration.Initialize(cachedDS, cachedLE, migration.DefaultCacheTTL) + + namespaces := []string{"default", "org-2", "org-3"} + numDashboardsPerNs := 3 + + for _, ns := range namespaces { + for i := 0; i < numDashboardsPerNs; i++ { + source := createTestV0Dashboard(ns, "Dashboard "+string(rune('A'+i))) + target := &dashv2alpha1.Dashboard{} + + err := Convert_V0_to_V2alpha1(source, target, nil, cachedDS, cachedLE) + require.NoError(t, err, "conversion for namespace %s should succeed", ns) + } + } + + // With caching, each namespace should result in one call to the underlying provider + expectedCalls := int64(len(namespaces)) + assert.Equal(t, expectedCalls, underlyingDS.getCallCount(), + "datasource provider should be called once per namespace (%d namespaces)", len(namespaces)) + assert.Equal(t, expectedCalls, underlyingLE.getCallCount(), + "library element provider should be called once per namespace (%d namespaces)", len(namespaces)) +} + +// TestConversionCaching_CacheDisabled verifies that TTL=0 disables caching +func TestConversionCaching_CacheDisabled(t *testing.T) { + datasources := []schemaversion.DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + elements := []schemaversion.LibraryElementInfo{ + {UID: "lib-panel-repeat-h", Name: "Library Panel with Horizontal Repeat", Type: "timeseries"}, + {UID: "lib-panel-no-repeat", Name: "Library Panel without Repeat", Type: "graph"}, + } + + underlyingDS := newCountingDataSourceProvider(datasources) + underlyingLE := newCountingLibraryElementProvider(elements) + + // TTL of 0 should disable caching - the wrapper returns the underlying provider directly + cachedDS := schemaversion.WrapIndexProviderWithCache(underlyingDS, 0) + cachedLE := schemaversion.WrapLibraryElementProviderWithCache(underlyingLE, 0) + + migration.ResetForTesting() + migration.Initialize(cachedDS, cachedLE, migration.DefaultCacheTTL) + + numDashboards := 3 + namespace := "default" + + for i := 0; i < numDashboards; i++ { + source := createTestV0Dashboard(namespace, "Dashboard "+string(rune('A'+i))) + target := &dashv2alpha1.Dashboard{} + + err := Convert_V0_to_V2alpha1(source, target, nil, cachedDS, cachedLE) + require.NoError(t, err, "conversion %d should succeed", i) + } + + // Without caching, each conversion calls the underlying provider multiple times + // (once for each datasource lookup needed - variables and panels) + // The key check is that the count is GREATER than 1 per conversion (no caching benefit) + assert.Greater(t, underlyingDS.getCallCount(), int64(numDashboards), + "with cache disabled, conversions should call datasource provider multiple times") + // Library element provider is also called for each conversion without caching + assert.GreaterOrEqual(t, underlyingLE.getCallCount(), int64(numDashboards), + "with cache disabled, conversions should call library element provider multiple times") +} diff --git a/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection.go b/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection.go index 296a95ac054..269fb51bd70 100644 --- a/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection.go +++ b/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection.go @@ -4,8 +4,6 @@ import ( "errors" "fmt" - "k8s.io/apimachinery/pkg/conversion" - dashv0 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1" dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1" dashv2alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1" @@ -121,6 +119,14 @@ func countPanelsV0V1(spec map[string]interface{}) int { return count } +// countTargetsFromPanel counts the number of targets/queries in a panel. +func countTargetsFromPanel(panelMap map[string]interface{}) int { + if targets, ok := panelMap["targets"].([]interface{}); ok { + return len(targets) + } + return 0 +} + // countQueriesV0V1 counts data queries in v0alpha1 or v1beta1 dashboard spec // Note: Row panels are layout containers and should not have queries. // We ignore any queries on row panels themselves, but count queries in their collapsed panels. @@ -145,9 +151,7 @@ func countQueriesV0V1(spec map[string]interface{}) int { // Count queries in regular panels (NOT row panels) if panelType != "row" { - if targets, ok := panelMap["targets"].([]interface{}); ok { - count += len(targets) - } + count += countTargetsFromPanel(panelMap) } // Count queries in collapsed panels inside row panels @@ -155,9 +159,7 @@ func countQueriesV0V1(spec map[string]interface{}) int { if collapsedPanels, ok := panelMap["panels"].([]interface{}); ok { for _, cp := range collapsedPanels { if cpMap, ok := cp.(map[string]interface{}); ok { - if targets, ok := cpMap["targets"].([]interface{}); ok { - count += len(targets) - } + count += countTargetsFromPanel(cpMap) } } } @@ -178,12 +180,15 @@ func countAnnotationsV0V1(spec map[string]interface{}) int { return 0 } - annotationList, ok := annotations["list"].([]interface{}) - if !ok { - return 0 + // Handle both []interface{} (from JSON unmarshaling) and []map[string]interface{} (from programmatic creation) + if annotationList, ok := annotations["list"].([]interface{}); ok { + return len(annotationList) + } + if annotationList, ok := annotations["list"].([]map[string]interface{}); ok { + return len(annotationList) } - return len(annotationList) + return 0 } // countLinksV0V1 counts dashboard links in v0alpha1 or v1beta1 dashboard spec @@ -192,12 +197,15 @@ func countLinksV0V1(spec map[string]interface{}) int { return 0 } - links, ok := spec["links"].([]interface{}) - if !ok { - return 0 + // Handle both []interface{} (from JSON unmarshaling) and []map[string]interface{} (from programmatic creation) + if links, ok := spec["links"].([]interface{}); ok { + return len(links) + } + if links, ok := spec["links"].([]map[string]interface{}); ok { + return len(links) } - return len(links) + return 0 } // countVariablesV0V1 counts template variables in v0alpha1 or v1beta1 dashboard spec @@ -211,12 +219,15 @@ func countVariablesV0V1(spec map[string]interface{}) int { return 0 } - variableList, ok := templating["list"].([]interface{}) - if !ok { - return 0 + // Handle both []interface{} (from JSON unmarshaling) and []map[string]interface{} (from programmatic creation) + if variableList, ok := templating["list"].([]interface{}); ok { + return len(variableList) + } + if variableList, ok := templating["list"].([]map[string]interface{}); ok { + return len(variableList) } - return len(variableList) + return 0 } // collectStatsV0V1 collects statistics from v0alpha1 or v1beta1 dashboard @@ -442,77 +453,3 @@ func collectDashboardStats(dashboard interface{}) dashboardStats { } return dashboardStats{} } - -// withConversionDataLossDetection wraps a conversion function to detect data loss -func withConversionDataLossDetection(sourceFuncName, targetFuncName string, conversionFunc func(a, b interface{}, scope conversion.Scope) error) func(a, b interface{}, scope conversion.Scope) error { - return func(a, b interface{}, scope conversion.Scope) error { - // Collect source statistics - var sourceStats dashboardStats - switch source := a.(type) { - case *dashv0.Dashboard: - if source.Spec.Object != nil { - sourceStats = collectStatsV0V1(source.Spec.Object) - } - case *dashv1.Dashboard: - if source.Spec.Object != nil { - sourceStats = collectStatsV0V1(source.Spec.Object) - } - case *dashv2alpha1.Dashboard: - sourceStats = collectStatsV2alpha1(source.Spec) - case *dashv2beta1.Dashboard: - sourceStats = collectStatsV2beta1(source.Spec) - } - - // Execute the conversion - err := conversionFunc(a, b, scope) - if err != nil { - return err - } - - // Collect target statistics - var targetStats dashboardStats - switch target := b.(type) { - case *dashv0.Dashboard: - if target.Spec.Object != nil { - targetStats = collectStatsV0V1(target.Spec.Object) - } - case *dashv1.Dashboard: - if target.Spec.Object != nil { - targetStats = collectStatsV0V1(target.Spec.Object) - } - case *dashv2alpha1.Dashboard: - targetStats = collectStatsV2alpha1(target.Spec) - case *dashv2beta1.Dashboard: - targetStats = collectStatsV2beta1(target.Spec) - } - - // Detect if data was lost - if dataLossErr := detectConversionDataLoss(sourceStats, targetStats, sourceFuncName, targetFuncName); dataLossErr != nil { - logger.Error("Dashboard conversion data loss detected", - "sourceFunc", sourceFuncName, - "targetFunc", targetFuncName, - "sourcePanels", sourceStats.panelCount, - "targetPanels", targetStats.panelCount, - "sourceQueries", sourceStats.queryCount, - "targetQueries", targetStats.queryCount, - "sourceAnnotations", sourceStats.annotationCount, - "targetAnnotations", targetStats.annotationCount, - "sourceLinks", sourceStats.linkCount, - "targetLinks", targetStats.linkCount, - "error", dataLossErr, - ) - return dataLossErr - } - - logger.Debug("Dashboard conversion completed without data loss", - "sourceFunc", sourceFuncName, - "targetFunc", targetFuncName, - "panels", targetStats.panelCount, - "queries", targetStats.queryCount, - "annotations", targetStats.annotationCount, - "links", targetStats.linkCount, - ) - - return nil - } -} diff --git a/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection_test.go b/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection_test.go index f49305996f9..5c28c98b861 100644 --- a/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection_test.go +++ b/apps/dashboard/pkg/migration/conversion/conversion_data_loss_detection_test.go @@ -410,158 +410,167 @@ func TestCountPanelsV2(t *testing.T) { } func TestDetectConversionDataLoss(t *testing.T) { - tests := []struct { - name string - sourceStats dashboardStats - targetStats dashboardStats - expectError bool - errorMsg string - }{ - { - name: "perfect match - no data loss", - sourceStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - variableCount: 2, + // Tests that expect NO error (no data loss) + t.Run("success cases", func(t *testing.T) { + successTests := []struct { + name string + sourceStats dashboardStats + targetStats dashboardStats + }{ + { + name: "perfect match - no data loss", + sourceStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + variableCount: 2, + }, + targetStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + variableCount: 2, + }, }, - targetStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - variableCount: 2, + { + name: "panel count increased (allowed)", + sourceStats: dashboardStats{ + panelCount: 2, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + }, + targetStats: dashboardStats{ + panelCount: 3, // Added a panel (OK) + queryCount: 5, + annotationCount: 2, + linkCount: 1, + }, }, - expectError: false, - }, - { - name: "panel count decreased (data loss)", - sourceStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, + { + name: "annotation count increased (allowed - default annotations)", + sourceStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 0, + linkCount: 1, + }, + targetStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 1, // Added default annotation (OK) + linkCount: 1, + }, }, - targetStats: dashboardStats{ - panelCount: 2, // Lost a panel! - queryCount: 5, - annotationCount: 2, - linkCount: 1, - }, - expectError: true, - errorMsg: "panel count decreased", - }, - { - name: "panel count increased (allowed)", - sourceStats: dashboardStats{ - panelCount: 2, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - }, - targetStats: dashboardStats{ - panelCount: 3, // Added a panel (OK) - queryCount: 5, - annotationCount: 2, - linkCount: 1, - }, - expectError: false, - }, - { - name: "query count decreased (data loss)", - sourceStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - }, - targetStats: dashboardStats{ - panelCount: 3, - queryCount: 3, // Lost queries! - annotationCount: 2, - linkCount: 1, - }, - expectError: true, - errorMsg: "query count decreased", - }, - { - name: "annotation count decreased (data loss)", - sourceStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - }, - targetStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 1, // Lost annotation! - linkCount: 1, - }, - expectError: true, - errorMsg: "annotation count decreased", - }, - { - name: "annotation count increased (allowed - default annotations)", - sourceStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 0, - linkCount: 1, - }, - targetStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 1, // Added default annotation (OK) - linkCount: 1, - }, - expectError: false, - }, - { - name: "variable count decreased (data loss)", - sourceStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - variableCount: 3, - }, - targetStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - variableCount: 1, // Lost variables! - }, - expectError: true, - errorMsg: "variable count decreased", - }, - { - name: "multiple decreases (data loss)", - sourceStats: dashboardStats{ - panelCount: 3, - queryCount: 5, - annotationCount: 2, - linkCount: 1, - variableCount: 2, - }, - targetStats: dashboardStats{ - panelCount: 2, // Lost panel - queryCount: 3, // Lost queries - annotationCount: 2, - linkCount: 0, // Lost link - variableCount: 2, - }, - expectError: true, - errorMsg: "panel count decreased", - }, - } + } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := detectConversionDataLoss(tt.sourceStats, tt.targetStats, "TestSource", "TestTarget") - if tt.expectError { + for _, tt := range successTests { + t.Run(tt.name, func(t *testing.T) { + err := detectConversionDataLoss(tt.sourceStats, tt.targetStats, "TestSource", "TestTarget") + assert.NoError(t, err) + }) + } + }) + + // Tests that expect an error (data loss detected) + t.Run("data loss cases", func(t *testing.T) { + errorTests := []struct { + name string + sourceStats dashboardStats + targetStats dashboardStats + errorMsg string + }{ + { + name: "panel count decreased (data loss)", + sourceStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + }, + targetStats: dashboardStats{ + panelCount: 2, // Lost a panel! + queryCount: 5, + annotationCount: 2, + linkCount: 1, + }, + errorMsg: "panel count decreased", + }, + { + name: "query count decreased (data loss)", + sourceStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + }, + targetStats: dashboardStats{ + panelCount: 3, + queryCount: 3, // Lost queries! + annotationCount: 2, + linkCount: 1, + }, + errorMsg: "query count decreased", + }, + { + name: "annotation count decreased (data loss)", + sourceStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + }, + targetStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 1, // Lost annotation! + linkCount: 1, + }, + errorMsg: "annotation count decreased", + }, + { + name: "variable count decreased (data loss)", + sourceStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + variableCount: 3, + }, + targetStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + variableCount: 1, // Lost variables! + }, + errorMsg: "variable count decreased", + }, + { + name: "multiple decreases (data loss)", + sourceStats: dashboardStats{ + panelCount: 3, + queryCount: 5, + annotationCount: 2, + linkCount: 1, + variableCount: 2, + }, + targetStats: dashboardStats{ + panelCount: 2, // Lost panel + queryCount: 3, // Lost queries + annotationCount: 2, + linkCount: 0, // Lost link + variableCount: 2, + }, + errorMsg: "panel count decreased", + }, + } + + for _, tt := range errorTests { + t.Run(tt.name, func(t *testing.T) { + err := detectConversionDataLoss(tt.sourceStats, tt.targetStats, "TestSource", "TestTarget") require.Error(t, err) assert.Contains(t, err.Error(), tt.errorMsg) @@ -569,11 +578,9 @@ func TestDetectConversionDataLoss(t *testing.T) { var detectConversionDataLossErr *ConversionDataLossError require.ErrorAs(t, err, &detectConversionDataLossErr) assert.Equal(t, "TestSource_to_TestTarget", detectConversionDataLossErr.GetFunctionName()) - } else { - assert.NoError(t, err) - } - }) - } + }) + } + }) } func TestCollectStatsV0V1(t *testing.T) { @@ -687,140 +694,692 @@ func TestConversionDataLossError(t *testing.T) { assert.Equal(t, "data loss detected in TestFunc (v0alpha1 → v1beta1): test error message", err.Error()) } -// Integration test showing how validation works with actual dashboard types -func TestWithConversionValidation_Integration(t *testing.T) { - // Create a source dashboard (v0) with specific counts - sourceV0 := &dashv0.Dashboard{ - Spec: dashv0.DashboardSpec{ - Object: map[string]interface{}{ - "panels": []interface{}{ - map[string]interface{}{ - "id": float64(1), - "type": "graph", - "targets": []interface{}{ - map[string]interface{}{"refId": "A"}, - }, - }, - map[string]interface{}{ - "id": float64(2), - "type": "table", - "targets": []interface{}{ - map[string]interface{}{"refId": "A"}, - map[string]interface{}{"refId": "B"}, - }, - }, - }, - "annotations": map[string]interface{}{ - "list": []interface{}{ - map[string]interface{}{"name": "Annotation 1"}, - }, - }, - "links": []interface{}{ - map[string]interface{}{"title": "Link 1"}, - }, - }, - }, - } +// TestWithConversionMetrics_DataLossOnlyCheckedOnSuccess verifies that the +// withConversionMetrics wrapper only runs data loss detection when conversion succeeds. +func TestWithConversionMetrics_DataLossOnlyCheckedOnSuccess(t *testing.T) { + conversionError := errors.New("conversion failed") - // Create a target dashboard (v1) with matching counts - targetV1 := &dashv1.Dashboard{ - Spec: dashv1.DashboardSpec{ - Object: map[string]interface{}{ - "panels": []interface{}{ - map[string]interface{}{ - "id": float64(1), - "type": "graph", - "targets": []interface{}{ - map[string]interface{}{"refId": "A"}, - }, - }, - map[string]interface{}{ - "id": float64(2), - "type": "table", - "targets": []interface{}{ - map[string]interface{}{"refId": "A"}, - map[string]interface{}{"refId": "B"}, - }, - }, - }, - "annotations": map[string]interface{}{ - "list": []interface{}{ - map[string]interface{}{"name": "Annotation 1"}, - }, - }, - "links": []interface{}{ - map[string]interface{}{"title": "Link 1"}, - }, - }, - }, - } + // Test 1: Conversion fails - data loss should NOT be checked + t.Run("data loss not checked when conversion fails", func(t *testing.T) { + mockFailingConversion := func(a, b interface{}, scope conversion.Scope) error { + return conversionError + } - // Mock conversion function that just copies the spec - mockConversion := func(a, b interface{}, scope conversion.Scope) error { - source := a.(*dashv0.Dashboard) - target := b.(*dashv1.Dashboard) - target.Spec = dashv1.DashboardSpec{Object: source.Spec.Object} - return nil - } + wrappedFunc := withConversionMetrics(dashv0.APIVERSION, dashv1.APIVERSION, mockFailingConversion) - // Wrap with validation - validatedFunc := withConversionDataLossDetection("V0", "V1beta1", mockConversion) - - // This should pass validation - err := validatedFunc(sourceV0, targetV1, nil) - assert.NoError(t, err) -} - -func TestWithConversionValidation_DataLoss(t *testing.T) { - // Create a source dashboard (v0) with 2 panels - sourceV0 := &dashv0.Dashboard{ - Spec: dashv0.DashboardSpec{ - Object: map[string]interface{}{ - "panels": []interface{}{ - map[string]interface{}{ - "id": float64(1), - "type": "graph", + sourceV0 := &dashv0.Dashboard{ + Spec: dashv0.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{"id": float64(1), "type": "graph"}, + map[string]interface{}{"id": float64(2), "type": "table"}, }, - map[string]interface{}{ - "id": float64(2), - "type": "table", - }, - }, - }, - }, - } - - targetV1 := &dashv1.Dashboard{} - - // Mock conversion function that loses a panel - mockBadConversion := func(a, b interface{}, scope conversion.Scope) error { - target := b.(*dashv1.Dashboard) - // Only copy 1 panel instead of 2 - target.Spec = dashv1.DashboardSpec{ - Object: map[string]interface{}{ - "panels": []interface{}{ - map[string]interface{}{ - "id": float64(1), - "type": "graph", - }, - // Missing panel 2! }, }, } - return nil + targetV1 := &dashv1.Dashboard{} // Empty - would trigger data loss if checked + + // Execute - withConversionMetrics always returns nil to avoid 500s + err := wrappedFunc(sourceV0, targetV1, nil) + require.NoError(t, err, "withConversionMetrics should return nil even on conversion failure") + }) + + // Test 2: Conversion succeeds but data loss occurs - should detect data loss + t.Run("data loss detected when conversion succeeds but loses data", func(t *testing.T) { + mockDataLosingConversion := func(a, b interface{}, scope conversion.Scope) error { + // Conversion "succeeds" but loses a panel + target := b.(*dashv1.Dashboard) + target.Spec = dashv1.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + // Only 1 panel instead of 2 + map[string]interface{}{"id": float64(1), "type": "graph"}, + }, + }, + } + return nil + } + + wrappedFunc := withConversionMetrics(dashv0.APIVERSION, dashv1.APIVERSION, mockDataLosingConversion) + + sourceV0 := &dashv0.Dashboard{ + Spec: dashv0.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{"id": float64(1), "type": "graph"}, + map[string]interface{}{"id": float64(2), "type": "table"}, + }, + }, + }, + } + targetV1 := &dashv1.Dashboard{} + + // Execute - withConversionMetrics always returns nil + err := wrappedFunc(sourceV0, targetV1, nil) + require.NoError(t, err, "withConversionMetrics should return nil even on data loss") + + // The data loss is logged and recorded in metrics, but no error is returned to API server + }) +} + +// TestDataLossDetectionReturnsCorrectError verifies that when data loss is detected, +// a ConversionDataLossError is returned with proper function name and details. +func TestDataLossDetectionReturnsCorrectError(t *testing.T) { + t.Run("panel loss returns ConversionDataLossError", func(t *testing.T) { + sourceV0 := &dashv0.Dashboard{ + Spec: dashv0.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{"id": float64(1), "type": "graph"}, + map[string]interface{}{"id": float64(2), "type": "table"}, + }, + }, + }, + } + + targetV1 := &dashv1.Dashboard{ + Spec: dashv1.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + // Missing panel 2 + map[string]interface{}{"id": float64(1), "type": "graph"}, + }, + }, + }, + } + + err := checkConversionDataLoss(dashv0.APIVERSION, dashv1.APIVERSION, sourceV0, targetV1) + + require.Error(t, err) + var dataLossErr *ConversionDataLossError + require.ErrorAs(t, err, &dataLossErr) + assert.Equal(t, "V0_to_V1", dataLossErr.GetFunctionName()) + assert.Contains(t, err.Error(), "panel count decreased") + }) + + t.Run("query loss returns ConversionDataLossError", func(t *testing.T) { + sourceV0 := &dashv0.Dashboard{ + Spec: dashv0.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + map[string]interface{}{"refId": "B"}, + }, + }, + }, + }, + }, + } + + targetV1 := &dashv1.Dashboard{ + Spec: dashv1.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + // Missing query B + map[string]interface{}{"refId": "A"}, + }, + }, + }, + }, + }, + } + + err := checkConversionDataLoss(dashv0.APIVERSION, dashv1.APIVERSION, sourceV0, targetV1) + + require.Error(t, err) + var dataLossErr *ConversionDataLossError + require.ErrorAs(t, err, &dataLossErr) + assert.Contains(t, err.Error(), "query count decreased") + }) + + t.Run("no data loss returns nil", func(t *testing.T) { + sourceV0 := &dashv0.Dashboard{ + Spec: dashv0.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + }, + }, + }, + } + + targetV1 := &dashv1.Dashboard{ + Spec: dashv1.DashboardSpec{ + Object: map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + }, + }, + }, + } + + err := checkConversionDataLoss(dashv0.APIVERSION, dashv1.APIVERSION, sourceV0, targetV1) + + require.NoError(t, err) + }) +} + +// TestDataLossDetection_AllTypesAllVersions verifies that data loss is detected for +// all types of loss (panels, queries, annotations, links, variables) across all +// version permutations (v0alpha1, v1beta1, v2alpha1, v2beta1). +func TestDataLossDetection_AllTypesAllVersions(t *testing.T) { + // Helper to create v0/v1 unstructured spec with data + createV0V1SpecWithData := func() map[string]interface{} { + return map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + map[string]interface{}{"refId": "B"}, + }, + }, + map[string]interface{}{ + "id": float64(2), + "type": "table", + "targets": []interface{}{ + map[string]interface{}{"refId": "C"}, + }, + }, + }, + "annotations": map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{"name": "Annotation 1"}, + map[string]interface{}{"name": "Annotation 2"}, + }, + }, + "links": []interface{}{ + map[string]interface{}{"title": "Link 1"}, + map[string]interface{}{"title": "Link 2"}, + }, + "templating": map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{"name": "var1", "type": "query"}, + map[string]interface{}{"name": "var2", "type": "custom"}, + }, + }, + } } - // Wrap with data loss detection - validatedFunc := withConversionDataLossDetection("V0", "V1beta1", mockBadConversion) + // Helper to create v0/v1 unstructured spec with data loss (missing items) + createV0V1SpecWithLoss := func(lossType string) map[string]interface{} { + spec := createV0V1SpecWithData() + switch lossType { + case "panel": + spec["panels"] = []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + map[string]interface{}{"refId": "B"}, + }, + }, + // Missing panel 2 + } + case "query": + spec["panels"] = []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + // Missing query B + }, + }, + map[string]interface{}{ + "id": float64(2), + "type": "table", + "targets": []interface{}{ + map[string]interface{}{"refId": "C"}, + }, + }, + } + case "annotation": + spec["annotations"] = map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{"name": "Annotation 1"}, + // Missing annotation 2 + }, + } + case "link": + spec["links"] = []interface{}{ + map[string]interface{}{"title": "Link 1"}, + // Missing link 2 + } + case "variable": + spec["templating"] = map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{"name": "var1", "type": "query"}, + // Missing var2 + }, + } + } + return spec + } - // This should fail due to data loss - err := validatedFunc(sourceV0, targetV1, nil) - require.Error(t, err) - assert.Contains(t, err.Error(), "panel count decreased") + // Helper to create v2alpha1 dashboard with data + createV2alpha1WithData := func() *dashv2alpha1.Dashboard { + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: map[string]dashv2alpha1.DashboardElement{ + "panel1": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 1, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}, + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "B"}}, + }, + }, + }, + }, + }, + }, + "panel2": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 2, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "C"}}, + }, + }, + }, + }, + }, + }, + }, + Annotations: []dashv2alpha1.DashboardAnnotationQueryKind{{}, {}}, + Links: []dashv2alpha1.DashboardDashboardLink{{}, {}}, + Variables: []dashv2alpha1.DashboardVariableKind{{}, {}}, + }, + } + } - var detectConversionDataLossErr *ConversionDataLossError - require.ErrorAs(t, err, &detectConversionDataLossErr) - assert.Equal(t, "V0_to_V1beta1", detectConversionDataLossErr.GetFunctionName()) + // Helper to create v2alpha1 dashboard with data loss + createV2alpha1WithLoss := func(lossType string) *dashv2alpha1.Dashboard { + dash := createV2alpha1WithData() + switch lossType { + case "panel": + delete(dash.Spec.Elements, "panel2") + case "query": + dash.Spec.Elements["panel1"].PanelKind.Spec.Data.Spec.Queries = []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}, + // Missing query B + } + case "annotation": + dash.Spec.Annotations = []dashv2alpha1.DashboardAnnotationQueryKind{{}} + case "link": + dash.Spec.Links = []dashv2alpha1.DashboardDashboardLink{{}} + case "variable": + dash.Spec.Variables = []dashv2alpha1.DashboardVariableKind{{}} + } + return dash + } + + // Helper to create v2beta1 dashboard with data + createV2beta1WithData := func() *dashv2beta1.Dashboard { + return &dashv2beta1.Dashboard{ + Spec: dashv2beta1.DashboardSpec{ + Elements: map[string]dashv2beta1.DashboardElement{ + "panel1": { + PanelKind: &dashv2beta1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2beta1.DashboardPanelSpec{ + Id: 1, + Data: dashv2beta1.DashboardQueryGroupKind{ + Spec: dashv2beta1.DashboardQueryGroupSpec{ + Queries: []dashv2beta1.DashboardPanelQueryKind{ + {Spec: dashv2beta1.DashboardPanelQuerySpec{RefId: "A"}}, + {Spec: dashv2beta1.DashboardPanelQuerySpec{RefId: "B"}}, + }, + }, + }, + }, + }, + }, + "panel2": { + PanelKind: &dashv2beta1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2beta1.DashboardPanelSpec{ + Id: 2, + Data: dashv2beta1.DashboardQueryGroupKind{ + Spec: dashv2beta1.DashboardQueryGroupSpec{ + Queries: []dashv2beta1.DashboardPanelQueryKind{ + {Spec: dashv2beta1.DashboardPanelQuerySpec{RefId: "C"}}, + }, + }, + }, + }, + }, + }, + }, + Annotations: []dashv2beta1.DashboardAnnotationQueryKind{{}, {}}, + Links: []dashv2beta1.DashboardDashboardLink{{}, {}}, + Variables: []dashv2beta1.DashboardVariableKind{{}, {}}, + }, + } + } + + // Helper to create v2beta1 dashboard with data loss + createV2beta1WithLoss := func(lossType string) *dashv2beta1.Dashboard { + dash := createV2beta1WithData() + switch lossType { + case "panel": + delete(dash.Spec.Elements, "panel2") + case "query": + dash.Spec.Elements["panel1"].PanelKind.Spec.Data.Spec.Queries = []dashv2beta1.DashboardPanelQueryKind{ + {Spec: dashv2beta1.DashboardPanelQuerySpec{RefId: "A"}}, + // Missing query B + } + case "annotation": + dash.Spec.Annotations = []dashv2beta1.DashboardAnnotationQueryKind{{}} + case "link": + dash.Spec.Links = []dashv2beta1.DashboardDashboardLink{{}} + case "variable": + dash.Spec.Variables = []dashv2beta1.DashboardVariableKind{{}} + } + return dash + } + + // All loss types to test + lossTypes := []struct { + name string + expectedErrMsg string + }{ + {"panel", "panel count decreased"}, + {"query", "query count decreased"}, + {"annotation", "annotation count decreased"}, + {"link", "link count decreased"}, + {"variable", "variable count decreased"}, + } + + // All version permutations (12 total: 4 versions × 3 targets each) + versionPairs := []struct { + sourceVersion string + targetVersion string + sourceAPI string + targetAPI string + }{ + // From v0alpha1 + {"v0alpha1", "v1beta1", dashv0.APIVERSION, dashv1.APIVERSION}, + {"v0alpha1", "v2alpha1", dashv0.APIVERSION, dashv2alpha1.APIVERSION}, + {"v0alpha1", "v2beta1", dashv0.APIVERSION, dashv2beta1.APIVERSION}, + // From v1beta1 + {"v1beta1", "v0alpha1", dashv1.APIVERSION, dashv0.APIVERSION}, + {"v1beta1", "v2alpha1", dashv1.APIVERSION, dashv2alpha1.APIVERSION}, + {"v1beta1", "v2beta1", dashv1.APIVERSION, dashv2beta1.APIVERSION}, + // From v2alpha1 + {"v2alpha1", "v0alpha1", dashv2alpha1.APIVERSION, dashv0.APIVERSION}, + {"v2alpha1", "v1beta1", dashv2alpha1.APIVERSION, dashv1.APIVERSION}, + {"v2alpha1", "v2beta1", dashv2alpha1.APIVERSION, dashv2beta1.APIVERSION}, + // From v2beta1 + {"v2beta1", "v0alpha1", dashv2beta1.APIVERSION, dashv0.APIVERSION}, + {"v2beta1", "v1beta1", dashv2beta1.APIVERSION, dashv1.APIVERSION}, + {"v2beta1", "v2alpha1", dashv2beta1.APIVERSION, dashv2alpha1.APIVERSION}, + } + + for _, vp := range versionPairs { + for _, lt := range lossTypes { + testName := fmt.Sprintf("%s_to_%s_%s_loss", vp.sourceVersion, vp.targetVersion, lt.name) + t.Run(testName, func(t *testing.T) { + var source, target interface{} + + // Create source dashboard with full data + switch vp.sourceVersion { + case "v0alpha1": + source = &dashv0.Dashboard{Spec: dashv0.DashboardSpec{Object: createV0V1SpecWithData()}} + case "v1beta1": + source = &dashv1.Dashboard{Spec: dashv1.DashboardSpec{Object: createV0V1SpecWithData()}} + case "v2alpha1": + source = createV2alpha1WithData() + case "v2beta1": + source = createV2beta1WithData() + } + + // Create target dashboard with data loss + switch vp.targetVersion { + case "v0alpha1": + target = &dashv0.Dashboard{Spec: dashv0.DashboardSpec{Object: createV0V1SpecWithLoss(lt.name)}} + case "v1beta1": + target = &dashv1.Dashboard{Spec: dashv1.DashboardSpec{Object: createV0V1SpecWithLoss(lt.name)}} + case "v2alpha1": + target = createV2alpha1WithLoss(lt.name) + case "v2beta1": + target = createV2beta1WithLoss(lt.name) + } + + // Check for data loss + err := checkConversionDataLoss(vp.sourceAPI, vp.targetAPI, source, target) + + // Verify data loss was detected + require.Error(t, err, "Expected %s loss to be detected for %s -> %s", lt.name, vp.sourceVersion, vp.targetVersion) + assert.Contains(t, err.Error(), lt.expectedErrMsg) + + // Verify it's a ConversionDataLossError + var dataLossErr *ConversionDataLossError + require.ErrorAs(t, err, &dataLossErr) + }) + } + } +} + +// TestDataLossDetection_NoFalsePositives_AllVersionPermutations verifies that no false positives +// are triggered for any attribute type when counts are equal or increased, across ALL version permutations. +func TestDataLossDetection_NoFalsePositives_AllVersionPermutations(t *testing.T) { + // Helper to create v0/v1 spec with data + createV0V1SpecWithData := func() map[string]interface{} { + return map[string]interface{}{ + "panels": []interface{}{ + map[string]interface{}{ + "id": float64(1), + "type": "graph", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + map[string]interface{}{"refId": "B"}, + }, + }, + map[string]interface{}{ + "id": float64(2), + "type": "table", + "targets": []interface{}{ + map[string]interface{}{"refId": "C"}, + }, + }, + }, + "annotations": map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{"name": "Annotation 1"}, + map[string]interface{}{"name": "Annotation 2"}, + }, + }, + "links": []interface{}{ + map[string]interface{}{"title": "Link 1"}, + map[string]interface{}{"title": "Link 2"}, + }, + "templating": map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{"name": "var1", "type": "query"}, + map[string]interface{}{"name": "var2", "type": "custom"}, + }, + }, + } + } + + // Helper to create v2alpha1 dashboard with data + createV2alpha1WithData := func() *dashv2alpha1.Dashboard { + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: map[string]dashv2alpha1.DashboardElement{ + "panel1": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 1, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}, + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "B"}}, + }, + }, + }, + }, + }, + }, + "panel2": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 2, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "C"}}, + }, + }, + }, + }, + }, + }, + }, + Annotations: []dashv2alpha1.DashboardAnnotationQueryKind{{}, {}}, + Links: []dashv2alpha1.DashboardDashboardLink{{}, {}}, + Variables: []dashv2alpha1.DashboardVariableKind{{}, {}}, + }, + } + } + + // Helper to create v2beta1 dashboard with data + createV2beta1WithData := func() *dashv2beta1.Dashboard { + return &dashv2beta1.Dashboard{ + Spec: dashv2beta1.DashboardSpec{ + Elements: map[string]dashv2beta1.DashboardElement{ + "panel1": { + PanelKind: &dashv2beta1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2beta1.DashboardPanelSpec{ + Id: 1, + Data: dashv2beta1.DashboardQueryGroupKind{ + Spec: dashv2beta1.DashboardQueryGroupSpec{ + Queries: []dashv2beta1.DashboardPanelQueryKind{ + {Spec: dashv2beta1.DashboardPanelQuerySpec{RefId: "A"}}, + {Spec: dashv2beta1.DashboardPanelQuerySpec{RefId: "B"}}, + }, + }, + }, + }, + }, + }, + "panel2": { + PanelKind: &dashv2beta1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2beta1.DashboardPanelSpec{ + Id: 2, + Data: dashv2beta1.DashboardQueryGroupKind{ + Spec: dashv2beta1.DashboardQueryGroupSpec{ + Queries: []dashv2beta1.DashboardPanelQueryKind{ + {Spec: dashv2beta1.DashboardPanelQuerySpec{RefId: "C"}}, + }, + }, + }, + }, + }, + }, + }, + Annotations: []dashv2beta1.DashboardAnnotationQueryKind{{}, {}}, + Links: []dashv2beta1.DashboardDashboardLink{{}, {}}, + Variables: []dashv2beta1.DashboardVariableKind{{}, {}}, + }, + } + } + + // All 12 version permutations + versionPairs := []struct { + sourceVersion string + targetVersion string + sourceAPI string + targetAPI string + }{ + // From v0alpha1 + {"v0alpha1", "v1beta1", dashv0.APIVERSION, dashv1.APIVERSION}, + {"v0alpha1", "v2alpha1", dashv0.APIVERSION, dashv2alpha1.APIVERSION}, + {"v0alpha1", "v2beta1", dashv0.APIVERSION, dashv2beta1.APIVERSION}, + // From v1beta1 + {"v1beta1", "v0alpha1", dashv1.APIVERSION, dashv0.APIVERSION}, + {"v1beta1", "v2alpha1", dashv1.APIVERSION, dashv2alpha1.APIVERSION}, + {"v1beta1", "v2beta1", dashv1.APIVERSION, dashv2beta1.APIVERSION}, + // From v2alpha1 + {"v2alpha1", "v0alpha1", dashv2alpha1.APIVERSION, dashv0.APIVERSION}, + {"v2alpha1", "v1beta1", dashv2alpha1.APIVERSION, dashv1.APIVERSION}, + {"v2alpha1", "v2beta1", dashv2alpha1.APIVERSION, dashv2beta1.APIVERSION}, + // From v2beta1 + {"v2beta1", "v0alpha1", dashv2beta1.APIVERSION, dashv0.APIVERSION}, + {"v2beta1", "v1beta1", dashv2beta1.APIVERSION, dashv1.APIVERSION}, + {"v2beta1", "v2alpha1", dashv2beta1.APIVERSION, dashv2alpha1.APIVERSION}, + } + + for _, vp := range versionPairs { + testName := fmt.Sprintf("%s_to_%s_no_loss", vp.sourceVersion, vp.targetVersion) + t.Run(testName, func(t *testing.T) { + var source, target interface{} + + // Create source dashboard with full data + switch vp.sourceVersion { + case "v0alpha1": + source = &dashv0.Dashboard{Spec: dashv0.DashboardSpec{Object: createV0V1SpecWithData()}} + case "v1beta1": + source = &dashv1.Dashboard{Spec: dashv1.DashboardSpec{Object: createV0V1SpecWithData()}} + case "v2alpha1": + source = createV2alpha1WithData() + case "v2beta1": + source = createV2beta1WithData() + } + + // Create target dashboard with same data (no loss) + switch vp.targetVersion { + case "v0alpha1": + target = &dashv0.Dashboard{Spec: dashv0.DashboardSpec{Object: createV0V1SpecWithData()}} + case "v1beta1": + target = &dashv1.Dashboard{Spec: dashv1.DashboardSpec{Object: createV0V1SpecWithData()}} + case "v2alpha1": + target = createV2alpha1WithData() + case "v2beta1": + target = createV2beta1WithData() + } + + // Check for data loss - should be none + err := checkConversionDataLoss(vp.sourceAPI, vp.targetAPI, source, target) + require.NoError(t, err, "Expected no data loss when data is preserved for %s -> %s", vp.sourceVersion, vp.targetVersion) + }) + } } // TestDataLossDetectionOnAllInputFiles tests all conversions from testdata/input @@ -829,7 +1388,7 @@ func TestDataLossDetectionOnAllInputFiles(t *testing.T) { // Initialize the migrator with a test data source provider dsProvider := testutil.NewDataSourceProvider(testutil.StandardTestConfig) leProvider := testutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() @@ -1359,3 +1918,1148 @@ func extractQueryInfoV2beta1(spec dashv2beta1.DashboardSpec) []queryInfo { return queries } + +// TestDataLossDetection_IntegrationWithRealConversions performs actual conversions +// using the scheme and verifies that data loss detection works correctly. +func TestDataLossDetection_IntegrationWithRealConversions(t *testing.T) { + // Initialize the migrator with a test data source provider + dsProvider := testutil.NewDataSourceProvider(testutil.StandardTestConfig) + leProvider := testutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + // Set up conversion scheme + scheme := runtime.NewScheme() + err := RegisterConversions(scheme, dsProvider, leProvider) + require.NoError(t, err) + + // + // ========== V0/V1 -> V2 CONVERSIONS (These should all pass) ========== + // + + // Test 1: V0 Collapsed Rows -> V2alpha1 + t.Run("Integration_V0CollapsedRows_To_V2alpha1", func(t *testing.T) { + source := &dashv0.Dashboard{ + TypeMeta: metav1.TypeMeta{ + APIVersion: dashv0.APIVERSION, + Kind: "Dashboard", + }, + Spec: dashv0.DashboardSpec{ + Object: createV0V1WithCollapsedRows(2, 2, 1), + }, + } + sourceStats := collectStatsV0V1(source.Spec.Object) + + target := &dashv2alpha1.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV2alpha1(target.Spec) + + t.Logf("V0 Collapsed Rows -> V2alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 2: V0 Expanded Rows -> V2alpha1 + t.Run("Integration_V0ExpandedRows_To_V2alpha1", func(t *testing.T) { + source := &dashv0.Dashboard{ + TypeMeta: metav1.TypeMeta{ + APIVersion: dashv0.APIVERSION, + Kind: "Dashboard", + }, + Spec: dashv0.DashboardSpec{ + Object: createV0V1WithExpandedRows(2, 2, 1), + }, + } + sourceStats := collectStatsV0V1(source.Spec.Object) + + target := &dashv2alpha1.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV2alpha1(target.Spec) + + t.Logf("V0 Expanded Rows -> V2alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 3: V0 Flat Panels -> V2alpha1 + t.Run("Integration_V0FlatPanels_To_V2alpha1", func(t *testing.T) { + source := &dashv0.Dashboard{ + TypeMeta: metav1.TypeMeta{ + APIVersion: dashv0.APIVERSION, + Kind: "Dashboard", + }, + Spec: dashv0.DashboardSpec{ + Object: createV0V1FlatPanels(4, 1), + }, + } + sourceStats := collectStatsV0V1(source.Spec.Object) + + target := &dashv2alpha1.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV2alpha1(target.Spec) + + t.Logf("V0 Flat Panels -> V2alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 4: V0 Mixed Layout -> V2alpha1 + t.Run("Integration_V0MixedLayout_To_V2alpha1", func(t *testing.T) { + source := &dashv0.Dashboard{ + TypeMeta: metav1.TypeMeta{ + APIVersion: dashv0.APIVERSION, + Kind: "Dashboard", + }, + Spec: dashv0.DashboardSpec{ + Object: createV0V1MixedAllTypes(), + }, + } + sourceStats := collectStatsV0V1(source.Spec.Object) + + target := &dashv2alpha1.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV2alpha1(target.Spec) + + t.Logf("V0 Mixed Layout -> V2alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // + // ========== V2 -> V0/V1 CONVERSIONS ========== + // These tests document the current state of V2 -> V0 conversions. + // + + // Test 5: V2 Simple Tabs -> V0alpha1 + t.Run("Integration_V2SimpleTabs_To_V0alpha1", func(t *testing.T) { + source := createV2DashboardWithSimpleTabs() + source.TypeMeta = metav1.TypeMeta{ + APIVersion: dashv2alpha1.APIVERSION, + Kind: "Dashboard", + } + sourceStats := collectStatsV2alpha1(source.Spec) + + target := &dashv0.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV0V1(target.Spec.Object) + + t.Logf("V2 Simple Tabs -> V0alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 6: V2 Rows Collapsed -> V0alpha1 + t.Run("Integration_V2RowsCollapsed_To_V0alpha1", func(t *testing.T) { + source := createV2DashboardWithRowsCollapsed() + source.TypeMeta = metav1.TypeMeta{ + APIVersion: dashv2alpha1.APIVERSION, + Kind: "Dashboard", + } + sourceStats := collectStatsV2alpha1(source.Spec) + + target := &dashv0.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV0V1(target.Spec.Object) + + t.Logf("V2 Rows Collapsed -> V0alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 7: V2 Rows Expanded -> V0alpha1 + t.Run("Integration_V2RowsExpanded_To_V0alpha1", func(t *testing.T) { + source := createV2DashboardWithRowsExpanded() + source.TypeMeta = metav1.TypeMeta{ + APIVersion: dashv2alpha1.APIVERSION, + Kind: "Dashboard", + } + sourceStats := collectStatsV2alpha1(source.Spec) + + target := &dashv0.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV0V1(target.Spec.Object) + + t.Logf("V2 Rows Expanded -> V0alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 8: V2 Tabs with Nested Rows -> V0alpha1 + t.Run("Integration_V2TabsWithNestedRows_To_V0alpha1", func(t *testing.T) { + source := createV2DashboardWithTabsAndNestedRows() + source.TypeMeta = metav1.TypeMeta{ + APIVersion: dashv2alpha1.APIVERSION, + Kind: "Dashboard", + } + sourceStats := collectStatsV2alpha1(source.Spec) + + target := &dashv0.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV0V1(target.Spec.Object) + + t.Logf("V2 Tabs with Nested Rows -> V0alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 9: V2 Rows with Nested Tabs -> V0alpha1 + t.Run("Integration_V2RowsWithNestedTabs_To_V0alpha1", func(t *testing.T) { + source := createV2DashboardWithRowsAndNestedTabs() + source.TypeMeta = metav1.TypeMeta{ + APIVersion: dashv2alpha1.APIVERSION, + Kind: "Dashboard", + } + sourceStats := collectStatsV2alpha1(source.Spec) + + target := &dashv0.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV0V1(target.Spec.Object) + + t.Logf("V2 Rows with Nested Tabs -> V0alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // Test 10: V2 Complex Nesting -> V0alpha1 + t.Run("Integration_V2ComplexNesting_To_V0alpha1", func(t *testing.T) { + source := createV2ComplexNestedDashboard() + source.TypeMeta = metav1.TypeMeta{ + APIVersion: dashv2alpha1.APIVERSION, + Kind: "Dashboard", + } + sourceStats := collectStatsV2alpha1(source.Spec) + + target := &dashv0.Dashboard{} + err := scheme.Convert(source, target, nil) + require.NoError(t, err, "Conversion should succeed") + + targetStats := collectStatsV0V1(target.Spec.Object) + + t.Logf("V2 Complex Nesting -> V0alpha1:") + t.Logf(" Source: panels=%d, queries=%d", sourceStats.panelCount, sourceStats.queryCount) + t.Logf(" Target: panels=%d, queries=%d", targetStats.panelCount, targetStats.queryCount) + + assert.Equal(t, sourceStats.panelCount, targetStats.panelCount, "Panel count should match") + assert.Equal(t, sourceStats.queryCount, targetStats.queryCount, "Query count should match") + }) + + // + // ========== ROUND-TRIP CONVERSIONS ========== + // + + // Test 11: V2 -> V0 -> V2 round-trip (panel count should be preserved) + t.Run("Integration_RoundTrip_V2_V0_V2", func(t *testing.T) { + original := createV2DashboardWithSimpleTabs() + original.TypeMeta = metav1.TypeMeta{ + APIVersion: dashv2alpha1.APIVERSION, + Kind: "Dashboard", + } + originalStats := collectStatsV2alpha1(original.Spec) + + // V2 -> V0 + intermediate := &dashv0.Dashboard{} + err := scheme.Convert(original, intermediate, nil) + require.NoError(t, err, "V2 -> V0 conversion should succeed") + intermediateStats := collectStatsV0V1(intermediate.Spec.Object) + + // V0 -> V2 + final := &dashv2alpha1.Dashboard{} + err = scheme.Convert(intermediate, final, nil) + require.NoError(t, err, "V0 -> V2 conversion should succeed") + finalStats := collectStatsV2alpha1(final.Spec) + + t.Logf("Round-trip V2 -> V0 -> V2:") + t.Logf(" Original (V2): panels=%d, queries=%d", originalStats.panelCount, originalStats.queryCount) + t.Logf(" Intermediate (V0): panels=%d, queries=%d", intermediateStats.panelCount, intermediateStats.queryCount) + t.Logf(" Final (V2): panels=%d, queries=%d", finalStats.panelCount, finalStats.queryCount) + + // Panel count should be preserved through round-trip + assert.Equal(t, originalStats.panelCount, finalStats.panelCount, "Panel count should match after round-trip") + + // Document query behavior + if intermediateStats.queryCount < originalStats.queryCount { + t.Logf(" ⚠️ Queries lost in V2->V0: %d -> %d", originalStats.queryCount, intermediateStats.queryCount) + } + if finalStats.queryCount != originalStats.queryCount { + t.Logf(" ⚠️ Final query count differs: original=%d, final=%d", originalStats.queryCount, finalStats.queryCount) + } + }) + + // Test 12: V0 -> V2 -> V0 round-trip + t.Run("Integration_RoundTrip_V0_V2_V0", func(t *testing.T) { + original := &dashv0.Dashboard{ + TypeMeta: metav1.TypeMeta{ + APIVersion: dashv0.APIVERSION, + Kind: "Dashboard", + }, + Spec: dashv0.DashboardSpec{ + Object: createV0V1MixedAllTypes(), + }, + } + originalStats := collectStatsV0V1(original.Spec.Object) + + // V0 -> V2 + intermediate := &dashv2alpha1.Dashboard{} + err := scheme.Convert(original, intermediate, nil) + require.NoError(t, err, "V0 -> V2 conversion should succeed") + intermediateStats := collectStatsV2alpha1(intermediate.Spec) + + // V2 -> V0 + final := &dashv0.Dashboard{} + err = scheme.Convert(intermediate, final, nil) + require.NoError(t, err, "V2 -> V0 conversion should succeed") + finalStats := collectStatsV0V1(final.Spec.Object) + + t.Logf("Round-trip V0 -> V2 -> V0:") + t.Logf(" Original (V0): panels=%d, queries=%d", originalStats.panelCount, originalStats.queryCount) + t.Logf(" Intermediate (V2): panels=%d, queries=%d", intermediateStats.panelCount, intermediateStats.queryCount) + t.Logf(" Final (V0): panels=%d, queries=%d", finalStats.panelCount, finalStats.queryCount) + + // V0 -> V2 should preserve everything + assert.Equal(t, originalStats.panelCount, intermediateStats.panelCount, "V0->V2 should preserve panels") + assert.Equal(t, originalStats.queryCount, intermediateStats.queryCount, "V0->V2 should preserve queries") + + // Document what happens in V2 -> V0 + assert.Equal(t, originalStats.panelCount, finalStats.panelCount, "Panel count should match after round-trip") + + if finalStats.queryCount < originalStats.queryCount { + t.Logf(" ⚠️ Queries lost in V2->V0 leg: %d -> %d", intermediateStats.queryCount, finalStats.queryCount) + } + }) +} + +// Helper functions to create test dashboards + +// ========== V2 Dashboard Fixtures ========== + +// createV2DashboardWithSimpleTabs creates a V2 dashboard with simple TabsLayout +// Structure: TabsLayout > Tab1[panel1, panel2] + Tab2[panel3, panel4] +func createV2DashboardWithSimpleTabs() *dashv2alpha1.Dashboard { + elements := map[string]dashv2alpha1.DashboardElement{} + for i := 1; i <= 4; i++ { + tabNum := (i-1)/2 + 1 + elements[fmt.Sprintf("panel%d", i)] = dashv2alpha1.DashboardElement{ + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: float64(i), + Title: fmt.Sprintf("Panel %d - Tab %d", i, tabNum), + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "timeseries"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}, + }, + }, + }, + }, + }, + } + } + + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: elements, + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + TabsLayoutKind: &dashv2alpha1.DashboardTabsLayoutKind{ + Kind: "TabsLayout", + Spec: dashv2alpha1.DashboardTabsLayoutSpec{ + Tabs: []dashv2alpha1.DashboardTabsLayoutTabKind{ + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab 1"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel1"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel2"}}}, + }, + }, + }, + }, + }, + }, + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab 2"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel3"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel4"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +// createV2DashboardWithRowsCollapsed creates a V2 dashboard with RowsLayout (collapsed rows) +// Structure: RowsLayout > Row1(collapsed)[panel1, panel2] + Row2(collapsed)[panel3, panel4] +func createV2DashboardWithRowsCollapsed() *dashv2alpha1.Dashboard { + elements := map[string]dashv2alpha1.DashboardElement{} + for i := 1; i <= 4; i++ { + rowNum := (i-1)/2 + 1 + elements[fmt.Sprintf("panel%d", i)] = dashv2alpha1.DashboardElement{ + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: float64(i), + Title: fmt.Sprintf("Panel %d - Row %d (collapsed)", i, rowNum), + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "timeseries"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}, + }, + }, + }, + }, + }, + } + } + + collapsed := true + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: elements, + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + RowsLayoutKind: &dashv2alpha1.DashboardRowsLayoutKind{ + Kind: "RowsLayout", + Spec: dashv2alpha1.DashboardRowsLayoutSpec{ + Rows: []dashv2alpha1.DashboardRowsLayoutRowKind{ + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 1 (collapsed)"), + Collapse: &collapsed, + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel1"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel2"}}}, + }, + }, + }, + }, + }, + }, + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 2 (collapsed)"), + Collapse: &collapsed, + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel3"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel4"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +// createV2DashboardWithRowsExpanded creates a V2 dashboard with RowsLayout (expanded rows) +// Structure: RowsLayout > Row1(expanded)[panel1, panel2] + Row2(expanded)[panel3, panel4] +func createV2DashboardWithRowsExpanded() *dashv2alpha1.Dashboard { + elements := map[string]dashv2alpha1.DashboardElement{} + for i := 1; i <= 4; i++ { + rowNum := (i-1)/2 + 1 + elements[fmt.Sprintf("panel%d", i)] = dashv2alpha1.DashboardElement{ + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: float64(i), + Title: fmt.Sprintf("Panel %d - Row %d (expanded)", i, rowNum), + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "timeseries"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{ + {Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}, + }, + }, + }, + }, + }, + } + } + + expanded := false // collapse=false means expanded + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: elements, + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + RowsLayoutKind: &dashv2alpha1.DashboardRowsLayoutKind{ + Kind: "RowsLayout", + Spec: dashv2alpha1.DashboardRowsLayoutSpec{ + Rows: []dashv2alpha1.DashboardRowsLayoutRowKind{ + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 1 (expanded)"), + Collapse: &expanded, + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel1"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel2"}}}, + }, + }, + }, + }, + }, + }, + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 2 (expanded)"), + Collapse: &expanded, + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel3"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel4"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func createV0V1FlatPanels(numPanels, queriesPerPanel int) map[string]interface{} { + panels := make([]interface{}, numPanels) + for i := 0; i < numPanels; i++ { + targets := make([]interface{}, queriesPerPanel) + for q := 0; q < queriesPerPanel; q++ { + targets[q] = map[string]interface{}{"refId": fmt.Sprintf("%c", 'A'+q)} + } + panels[i] = map[string]interface{}{ + "id": float64(i + 1), + "title": fmt.Sprintf("Panel %d", i+1), + "type": "timeseries", + "targets": targets, + } + } + return map[string]interface{}{"panels": panels} +} + +func createV0V1WithCollapsedRows(numRows, panelsPerRow, queriesPerPanel int) map[string]interface{} { + panels := make([]interface{}, 0) + panelID := 1 + + for r := 0; r < numRows; r++ { + // Create collapsed panels for this row + collapsedPanels := make([]interface{}, panelsPerRow) + for p := 0; p < panelsPerRow; p++ { + targets := make([]interface{}, queriesPerPanel) + for q := 0; q < queriesPerPanel; q++ { + targets[q] = map[string]interface{}{"refId": fmt.Sprintf("%c", 'A'+q)} + } + collapsedPanels[p] = map[string]interface{}{ + "id": float64(panelID), + "title": fmt.Sprintf("Panel %d (in Row %d)", panelID, r+1), + "type": "timeseries", + "targets": targets, + } + panelID++ + } + + // Add row with collapsed panels + panels = append(panels, map[string]interface{}{ + "id": float64(100 + r), + "title": fmt.Sprintf("Row %d (collapsed)", r+1), + "type": "row", + "collapsed": true, + "panels": collapsedPanels, + }) + } + return map[string]interface{}{"panels": panels} +} + +func createV0V1WithExpandedRows(numRows, panelsPerRow, queriesPerPanel int) map[string]interface{} { + panels := make([]interface{}, 0) + panelID := 1 + + for r := 0; r < numRows; r++ { + // Add expanded row (no nested panels) + panels = append(panels, map[string]interface{}{ + "id": float64(100 + r), + "title": fmt.Sprintf("Row %d (expanded)", r+1), + "type": "row", + // No "panels" field when row is expanded + }) + + // Add panels after the row + for p := 0; p < panelsPerRow; p++ { + targets := make([]interface{}, queriesPerPanel) + for q := 0; q < queriesPerPanel; q++ { + targets[q] = map[string]interface{}{"refId": fmt.Sprintf("%c", 'A'+q)} + } + panels = append(panels, map[string]interface{}{ + "id": float64(panelID), + "title": fmt.Sprintf("Panel %d (after Row %d)", panelID, r+1), + "type": "timeseries", + "targets": targets, + }) + panelID++ + } + } + return map[string]interface{}{"panels": panels} +} + +func createV2DashboardWithTabsAndNestedRows() *dashv2alpha1.Dashboard { + // 2 tabs, each with 1 row containing 2 panels = 4 panels total + // Structure: TabsLayout > Tab1[RowsLayout > Row[panel1, panel2]] + Tab2[RowsLayout > Row[panel3, panel4]] + elements := map[string]dashv2alpha1.DashboardElement{ + "panel1": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 1, Title: "Panel 1 - Tab1/Row1", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "timeseries"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + "panel2": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 2, Title: "Panel 2 - Tab1/Row1", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "stat"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + "panel3": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 3, Title: "Panel 3 - Tab2/Row1", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "gauge"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + "panel4": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 4, Title: "Panel 4 - Tab2/Row1", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "table"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + } + + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: elements, + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + TabsLayoutKind: &dashv2alpha1.DashboardTabsLayoutKind{ + Kind: "TabsLayout", + Spec: dashv2alpha1.DashboardTabsLayoutSpec{ + Tabs: []dashv2alpha1.DashboardTabsLayoutTabKind{ + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab 1"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + RowsLayoutKind: &dashv2alpha1.DashboardRowsLayoutKind{ + Kind: "RowsLayout", + Spec: dashv2alpha1.DashboardRowsLayoutSpec{ + Rows: []dashv2alpha1.DashboardRowsLayoutRowKind{ + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 1"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel1"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel2"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab 2"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + RowsLayoutKind: &dashv2alpha1.DashboardRowsLayoutKind{ + Kind: "RowsLayout", + Spec: dashv2alpha1.DashboardRowsLayoutSpec{ + Rows: []dashv2alpha1.DashboardRowsLayoutRowKind{ + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 1"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel3"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel4"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func createV2DashboardWithRowsAndNestedTabs() *dashv2alpha1.Dashboard { + // 2 rows, each containing a tab layout with 2 panels = 4 panels total + // Structure: RowsLayout > Row1[TabsLayout > Tab[panel1, panel2]] + Row2[TabsLayout > Tab[panel3, panel4]] + elements := map[string]dashv2alpha1.DashboardElement{ + "panel1": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 1, Title: "Panel 1 - Row1/TabA", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "timeseries"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + "panel2": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 2, Title: "Panel 2 - Row1/TabB", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "stat"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + "panel3": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 3, Title: "Panel 3 - Row2/TabA", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "gauge"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + "panel4": { + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: 4, Title: "Panel 4 - Row2/TabB", + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "table"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + }, + } + + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: elements, + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + RowsLayoutKind: &dashv2alpha1.DashboardRowsLayoutKind{ + Kind: "RowsLayout", + Spec: dashv2alpha1.DashboardRowsLayoutSpec{ + Rows: []dashv2alpha1.DashboardRowsLayoutRowKind{ + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 1"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + TabsLayoutKind: &dashv2alpha1.DashboardTabsLayoutKind{ + Kind: "TabsLayout", + Spec: dashv2alpha1.DashboardTabsLayoutSpec{ + Tabs: []dashv2alpha1.DashboardTabsLayoutTabKind{ + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab A"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel1"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel2"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 2"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + TabsLayoutKind: &dashv2alpha1.DashboardTabsLayoutKind{ + Kind: "TabsLayout", + Spec: dashv2alpha1.DashboardTabsLayoutSpec{ + Tabs: []dashv2alpha1.DashboardTabsLayoutTabKind{ + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab A"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel3"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel4"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func createV2ComplexNestedDashboard() *dashv2alpha1.Dashboard { + // Complex: 2 tabs, Tab1 has 2 rows (each with 2 panels), Tab2 has 2 panels directly + // Total: 6 panels + // Structure: TabsLayout > Tab1[RowsLayout > Row1[p1,p2] + Row2[p3,p4]] + Tab2[GridLayout > p5,p6] + elements := map[string]dashv2alpha1.DashboardElement{} + for i := 1; i <= 6; i++ { + elements[fmt.Sprintf("panel%d", i)] = dashv2alpha1.DashboardElement{ + PanelKind: &dashv2alpha1.DashboardPanelKind{ + Kind: "Panel", + Spec: dashv2alpha1.DashboardPanelSpec{ + Id: float64(i), + Title: fmt.Sprintf("Panel %d", i), + VizConfig: dashv2alpha1.DashboardVizConfigKind{Kind: "timeseries"}, + Data: dashv2alpha1.DashboardQueryGroupKind{ + Spec: dashv2alpha1.DashboardQueryGroupSpec{ + Queries: []dashv2alpha1.DashboardPanelQueryKind{{Spec: dashv2alpha1.DashboardPanelQuerySpec{RefId: "A"}}}, + }, + }, + }, + }, + } + } + + return &dashv2alpha1.Dashboard{ + Spec: dashv2alpha1.DashboardSpec{ + Elements: elements, + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + TabsLayoutKind: &dashv2alpha1.DashboardTabsLayoutKind{ + Kind: "TabsLayout", + Spec: dashv2alpha1.DashboardTabsLayoutSpec{ + Tabs: []dashv2alpha1.DashboardTabsLayoutTabKind{ + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab 1"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + RowsLayoutKind: &dashv2alpha1.DashboardRowsLayoutKind{ + Kind: "RowsLayout", + Spec: dashv2alpha1.DashboardRowsLayoutSpec{ + Rows: []dashv2alpha1.DashboardRowsLayoutRowKind{ + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 1"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel1"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel2"}}}, + }, + }, + }, + }, + }, + }, + { + Kind: "RowsLayoutRow", + Spec: dashv2alpha1.DashboardRowsLayoutRowSpec{ + Title: ptrString("Row 2"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel3"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel4"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + Kind: "TabsLayoutTab", + Spec: dashv2alpha1.DashboardTabsLayoutTabSpec{ + Title: ptrString("Tab 2"), + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{ + Items: []dashv2alpha1.DashboardGridLayoutItemKind{ + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel5"}}}, + {Spec: dashv2alpha1.DashboardGridLayoutItemSpec{Element: dashv2alpha1.DashboardElementReference{Name: "panel6"}}}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +// createV0V1MixedAllTypes creates a V0/V1 dashboard with ALL layout types: +// - Panels out of rows (flat, top-level) +// - Collapsed row with nested panels +// - Expanded row followed by panels +// Structure: [p1, p2, Row1(collapsed){p3,p4}, Row2(expanded), p5, p6] +// Total: 6 panels +func createV0V1MixedAllTypes() map[string]interface{} { + panels := []interface{}{ + // Flat panels out of rows (at the beginning) + map[string]interface{}{ + "id": float64(1), + "title": "Panel 1 (flat, no row)", + "type": "timeseries", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + map[string]interface{}{ + "id": float64(2), + "title": "Panel 2 (flat, no row)", + "type": "stat", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + + // Collapsed row with nested panels + map[string]interface{}{ + "id": float64(100), + "title": "Row 1 (collapsed)", + "type": "row", + "collapsed": true, + "panels": []interface{}{ + map[string]interface{}{ + "id": float64(3), + "title": "Panel 3 (in collapsed row)", + "type": "gauge", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + map[string]interface{}{ + "id": float64(4), + "title": "Panel 4 (in collapsed row)", + "type": "table", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + }, + }, + + // Expanded row (empty, panels follow after) + map[string]interface{}{ + "id": float64(101), + "title": "Row 2 (expanded)", + "type": "row", + // No "panels" field when row is expanded + }, + + // Panels after expanded row + map[string]interface{}{ + "id": float64(5), + "title": "Panel 5 (after expanded row)", + "type": "bargauge", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + map[string]interface{}{ + "id": float64(6), + "title": "Panel 6 (after expanded row)", + "type": "piechart", + "targets": []interface{}{ + map[string]interface{}{"refId": "A"}, + }, + }, + } + + return map[string]interface{}{"panels": panels} +} + +// ptrString is a helper to create a pointer to a string +func ptrString(s string) *string { + return &s +} diff --git a/apps/dashboard/pkg/migration/conversion/conversion_test.go b/apps/dashboard/pkg/migration/conversion/conversion_test.go index 88dfb683225..63338e7ea70 100644 --- a/apps/dashboard/pkg/migration/conversion/conversion_test.go +++ b/apps/dashboard/pkg/migration/conversion/conversion_test.go @@ -35,7 +35,7 @@ func TestConversionMatrixExist(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) versions := []metav1.Object{ &dashv0.Dashboard{Spec: common.Unstructured{Object: map[string]any{"title": "dashboardV0"}}}, @@ -89,7 +89,7 @@ func TestDashboardConversionToAllVersions(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() @@ -309,7 +309,7 @@ func TestMigratedDashboardsConversion(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() @@ -428,7 +428,7 @@ func setupTestConversionScheme(t *testing.T) *runtime.Scheme { t.Helper() dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) scheme := runtime.NewScheme() err := RegisterConversions(scheme, dsProvider, leProvider) @@ -527,7 +527,7 @@ func TestConversionMetrics(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Create a test registry for metrics registry := prometheus.NewRegistry() @@ -694,7 +694,7 @@ func TestConversionMetricsWrapper(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Create a test registry for metrics registry := prometheus.NewRegistry() @@ -864,7 +864,7 @@ func TestSchemaVersionExtraction(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Create a test registry for metrics registry := prometheus.NewRegistry() @@ -910,7 +910,7 @@ func TestConversionLogging(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Create a test registry for metrics registry := prometheus.NewRegistry() @@ -1003,7 +1003,7 @@ func TestConversionLogLevels(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) t.Run("log levels and structured fields verification", func(t *testing.T) { // Create test wrapper to verify logging behavior @@ -1076,7 +1076,7 @@ func TestConversionLoggingFields(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) // Use TestLibraryElementProvider for tests that need library panel models with repeat options leProvider := migrationtestutil.NewTestLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) t.Run("verify all log fields are present", func(t *testing.T) { // Test that the conversion wrapper includes all expected structured fields diff --git a/apps/dashboard/pkg/migration/conversion/metrics.go b/apps/dashboard/pkg/migration/conversion/metrics.go index 5b2700bce60..9cbdec193e8 100644 --- a/apps/dashboard/pkg/migration/conversion/metrics.go +++ b/apps/dashboard/pkg/migration/conversion/metrics.go @@ -17,7 +17,9 @@ import ( "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion" ) -var logger = logging.DefaultLogger.With("logger", "dashboard.conversion") +func getLogger() logging.Logger { + return logging.DefaultLogger.With("logger", "dashboard.conversion") +} // getErroredSchemaVersionFunc determines the schema version function that errored func getErroredSchemaVersionFunc(err error) string { @@ -83,20 +85,20 @@ func withConversionMetrics(sourceVersionAPI, targetVersionAPI string, conversion // Only track schema versions for v0/v1 dashboards (v2+ info is redundant with API version) switch source := a.(type) { case *dashv0.Dashboard: - dashboardUID = string(source.UID) + dashboardUID = source.Name if source.Spec.Object != nil { sourceSchemaVersion = schemaversion.GetSchemaVersion(source.Spec.Object) } case *dashv1.Dashboard: - dashboardUID = string(source.UID) + dashboardUID = source.Name if source.Spec.Object != nil { sourceSchemaVersion = schemaversion.GetSchemaVersion(source.Spec.Object) } case *dashv2alpha1.Dashboard: - dashboardUID = string(source.UID) + dashboardUID = source.Name // Don't track schema version for v2+ (redundant with API version) case *dashv2beta1.Dashboard: - dashboardUID = string(source.UID) + dashboardUID = source.Name // Don't track schema version for v2+ (redundant with API version) } @@ -197,9 +199,9 @@ func withConversionMetrics(sourceVersionAPI, targetVersionAPI string, conversion ) if errorType == "schema_minimum_version_error" { - logger.Warn("Dashboard conversion failed", logFields...) + getLogger().Warn("Dashboard conversion failed", logFields...) } else { - logger.Error("Dashboard conversion failed", logFields...) + getLogger().Error("Dashboard conversion failed", logFields...) } } else { // Record success metrics @@ -235,7 +237,7 @@ func withConversionMetrics(sourceVersionAPI, targetVersionAPI string, conversion ) } - logger.Debug("Dashboard conversion succeeded", successLogFields...) + getLogger().Debug("Dashboard conversion succeeded", successLogFields...) } return nil diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.json b/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.json index 89ce80876d2..e4e6f8831da 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.json @@ -300,15 +300,9 @@ "y": 0 }, "id": 6, - "options": { - "code": { - "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" - }, + "options": {}, + "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", "targets": [ { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.json b/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.json index 863d7b2a102..62648d7a4aa 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.json @@ -71,14 +71,13 @@ "id": 1, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": false, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -150,14 +149,13 @@ "id": 4, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -229,14 +227,13 @@ "id": 3, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -271,85 +268,6 @@ "title": "Center and bar glow", "type": "radialbar" }, - { - "datasource": { - "type": "grafana-testdata-datasource" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 4, - "x": 12, - "y": 1 - }, - "id": 5, - "maxDataPoints": 20, - "options": { - "barWidthFactor": 0.4, - "effects": { - "barGlow": true, - "centerGlow": true, - "rounded": true, - "spotlight": true - }, - "gradient": "none", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "segmentCount": 1, - "segmentSpacing": 0.3, - "shape": "circle", - "showThresholdLabels": false, - "showThresholdMarkers": false, - "sparkline": false - }, - "pluginVersion": "13.0.0-pre", - "targets": [ - { - "alias": "1", - "datasource": { - "type": "grafana-testdata-datasource" - }, - "max": 100, - "min": 1, - "noise": 22, - "refId": "A", - "scenarioId": "random_walk", - "spread": 22, - "startValue": 1 - } - ], - "title": "Spotlight", - "type": "radialbar" - }, { "datasource": { "type": "grafana-testdata-datasource" @@ -391,10 +309,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", + "barShape": "rounded", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -470,10 +387,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -549,10 +465,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -641,10 +556,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", + "barShape": "rounded", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -720,10 +634,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", + "barShape": "rounded", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -799,10 +712,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", + "barShape": "rounded", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -878,10 +790,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", + "barShape": "rounded", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -974,10 +885,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1053,10 +963,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1132,10 +1041,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1211,10 +1119,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1290,10 +1197,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1386,10 +1292,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1469,10 +1374,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1552,10 +1456,9 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", + "barShape": "flat", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1641,14 +1544,14 @@ "options": { "barWidth": 12, "barWidthFactor": 0.4, + "barShape": "rounded", "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "endpointMarker": "glow", "glow": "both", - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1662,8 +1565,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1730,11 +1632,10 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "barShape": "rounded", "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1748,8 +1649,7 @@ "shape": "gauge", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": true, - "spotlight": true + "sparkline": true }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1830,11 +1730,10 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "barShape": "rounded", "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1848,8 +1747,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1917,12 +1815,9 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "sparkline": false, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1934,10 +1829,10 @@ "segmentCount": 12, "segmentSpacing": 0.3, "shape": "circle", + "barShape": "rounded", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2004,11 +1899,10 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "barShape": "rounded", "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2022,8 +1916,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2090,11 +1983,10 @@ "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "barShape": "rounded", "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2108,8 +2000,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2147,4 +2038,4 @@ "title": "Panel tests - Gauge (new)", "uid": "panel-tests-gauge-new", "weekStart": "" -} \ No newline at end of file +} diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.json b/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.json index d4dd7980100..dda0fbcd432 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.json @@ -955,10 +955,8 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1162,4 +1160,4 @@ "title": "Panel tests - Old gauge to new", "uid": "panel-tests-old-gauge-to-new", "weekStart": "" -} \ No newline at end of file +} diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.angular-migrations.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.angular-migrations.json new file mode 100644 index 00000000000..3d496f51731 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.angular-migrations.json @@ -0,0 +1,1310 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v1beta1", + "metadata": { + "name": "angular-migrations-test" + }, + "spec": { + "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" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [ + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate graph panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate graph panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate table (old) panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate table (old) panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate piechart panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate piechart panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate worldmap panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate worldmap panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate stat panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate stat panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate (TRUE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate (FALSE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Disable angular (TRUE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.disableAngular=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Disable angular (FALSE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.disableAngular=false" + } + ], + "liveNow": false, + "panels": [ + { + "aliasColors": {}, + "type": "graph", + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.0.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk", + "seriesCount": 3 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 0 + }, + "id": 6, + "options": { + "code": { + "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", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "aliasColors": {}, + "autoMigrateFrom": "graph", + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.0.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.260951647569786,\n 1.887442338051216,\n 2.1526144400893514,\n 1.7287721375237766,\n 1.7262902137793208\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod1\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 1.589539045095202,\n 1.5914283506847613,\n 1.8976990616650726,\n 1.758223085999124,\n 2.2294649594813816\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod2\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.0914263380328766,\n 1.8164545521094575,\n 1.621111084665713,\n 1.3902653996444705,\n 1.482803315949775\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph - x axis series mode", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "barchart", + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 11 + }, + "id": 29, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar chart panel\n", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "aliasColors": {}, + "autoMigrateFrom": "graph", + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.3.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 28, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph - x axis series mode (with legend calcs)", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "bargauge", + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "autoMigrateFrom": "graph", + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 30, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.0.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk", + "seriesCount": 3 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph - x axis histogram mode", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "histogram", + "xaxis": { + "mode": "histogram", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:193", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:194", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 22 + }, + "id": 33, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar gauge panel\n", + "mode": "markdown" + }, + "pluginVersion": "11.3.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 22 + }, + "id": 31, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Histogram panel\n", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "table-old", + "columns": [], + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fontSize": "100%", + "gridPos": { + "h": 10, + "w": 16, + "x": 0, + "y": 33 + }, + "id": 2, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "showRowNums": false + }, + "pluginVersion": "9.5.0-pre", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "right", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk_table" + } + ], + "title": "Table (old)", + "transform": "table", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 33 + }, + "id": 7, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Table (old) \u003e\u003e Table\n\nKnown issues:\n* wrapping text\n* style changes", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "grafana-singlestat-panel", + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "grafana-testdata-datasource" + }, + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 43 + }, + "id": 9, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "thresholds": "", + "title": "grafana-singlestat-panel", + "type": "stat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 43 + }, + "id": 23, + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "singlestat (old, internal. Migrated if schema \u003c 28)", + "type": "stat" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 43 + }, + "id": 10, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Singlestat \u003e\u003e Stat\n\nKnown issues:\n* limited options", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "grafana-piechart-panel", + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 16, + "x": 0, + "y": 51 + }, + "id": 24, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk_table" + } + ], + "title": "grafana-piechart-panel", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "piechart" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 51 + }, + "id": 25, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-piechart-panel \u003e\u003e piechart\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "grafana-worldmap-panel", + "circleMaxSize": 30, + "circleMinSize": 2, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": { + "type": "grafana-testdata-datasource" + }, + "decimals": 0, + "esMetric": "Count", + "gridPos": { + "h": 10, + "w": 16, + "x": 0, + "y": 61 + }, + "hideEmpty": false, + "hideZero": false, + "id": 26, + "initialZoom": 1, + "locationData": "countries", + "mapCenter": "(0°, 0°)", + "mapCenterLatitude": 0, + "mapCenterLongitude": 0, + "maxDataPoints": 1, + "mouseWheelZoom": false, + "options": { + "basemap": { + "name": "Basemap", + "type": "default" + }, + "controls": { + "mouseWheelZoom": false, + "showAttribution": true, + "showDebug": false, + "showMeasure": false, + "showScale": false, + "showZoom": true + }, + "layers": [ + { + "config": { + "showLegend": true, + "style": { + "color": { + "fixed": "dark-green" + }, + "opacity": 0.4, + "rotation": { + "fixed": 0, + "max": 360, + "min": -360, + "mode": "mod" + }, + "size": { + "fixed": 5, + "max": 30, + "min": 2 + }, + "symbol": { + "fixed": "img/icons/marker/circle.svg", + "mode": "fixed" + }, + "symbolAlign": { + "horizontal": "center", + "vertical": "center" + }, + "textConfig": { + "fontSize": 12, + "offsetX": 0, + "offsetY": 0, + "textAlign": "center", + "textBaseline": "middle" + } + } + }, + "location": { + "gazetteer": "public/gazetteer/countries.json", + "mode": "lookup" + }, + "name": "Layer 0", + "tooltip": true, + "type": "markers" + } + ], + "tooltip": { + "mode": "details" + }, + "view": { + "allLayers": true, + "id": "zero", + "lat": 0, + "lon": 0, + "zoom": 1 + } + }, + "pluginVersion": "10.4.0-pre", + "showLegend": true, + "stickyLabels": false, + "tableQueryOptions": { + "geohashField": "geohash", + "latitudeField": "latitude", + "longitudeField": "longitude", + "metricField": "metric", + "queryType": "geohash" + }, + "targets": [ + { + "csvFileName": "flight_info_by_state.csv", + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "csv_file" + } + ], + "thresholds": "0,10", + "title": "grafana-worldmap-panel", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + }, + { + "id": "reduce", + "options": { + "reducers": [ + "sum" + ] + } + } + ], + "type": "geomap", + "unitPlural": "", + "unitSingle": "", + "valueName": "total" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 61 + }, + "id": 27, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-worldmap-panel \u003e\u003e geomap\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + } + ], + "refresh": "", + "schemaVersion": 42, + "tags": [ + "gdev", + "migrations", + "angular" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Devenv - Panel migrations", + "uid": "cdd412c4", + "weekStart": "" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.bom-in-links.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.bom-in-links.json new file mode 100644 index 00000000000..86992c3380c --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.bom-in-links.json @@ -0,0 +1,142 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v1beta1", + "metadata": { + "name": "bom-in-links-test", + "namespace": "org-1", + "labels": { + "test": "bom-stripping" + } + }, + "spec": { + "title": "BOM Stripping Test Dashboard", + "description": "Testing that BOM characters are stripped from URLs during conversion", + "schemaVersion": 42, + "tags": ["test", "bom"], + "editable": true, + "links": [ + { + "title": "Dashboard link with BOM", + "type": "link", + "url": "http://example.com?var=${datasource}&other=value", + "targetBlank": true, + "icon": "external link" + } + ], + "panels": [ + { + "id": 1, + "type": "table", + "title": "Panel with BOM in field config override links", + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + {"color": "green"}, + {"color": "red", "value": 80} + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "server" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Override link with BOM", + "url": "http://localhost:3000/d/test?var-datacenter=${__data.fields[datacenter]}&var-server=${__value.raw}" + } + ] + } + ] + } + ] + }, + "links": [ + { + "title": "Panel data link with BOM", + "url": "http://example.com/${__data.fields.cluster}&var=value", + "targetBlank": true + } + ], + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "test-ds" + } + } + ] + }, + { + "id": 2, + "type": "timeseries", + "title": "Panel with BOM in options dataLinks", + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "options": { + "legend": { + "showLegend": true, + "displayMode": "list", + "placement": "bottom" + }, + "dataLinks": [ + { + "title": "Options data link with BOM", + "url": "http://example.com?series=${__series.name}&time=${__value.time}", + "targetBlank": true + } + ] + }, + "fieldConfig": { + "defaults": { + "links": [ + { + "title": "Field config default link with BOM", + "url": "http://example.com?field=${__field.name}&value=${__value.raw}", + "targetBlank": false + } + ] + }, + "overrides": [] + }, + "targets": [ + { + "refId": "A", + "datasource": { + "type": "prometheus", + "uid": "test-ds" + } + } + ] + } + ], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m"] + } + } +} + diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.groupby.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.groupby.json new file mode 100644 index 00000000000..88527ef6036 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.groupby.json @@ -0,0 +1,166 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v1beta1", + "metadata": { + "name": "groupby-test" + }, + "spec": { + "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" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "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": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "editorMode": "code", + "expr": "sum(counters_requests)", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "works with group by var", + "type": "timeseries" + } + ], + "preload": false, + "schemaVersion": 42, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ], + "value": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "name": "Group by", + "type": "groupby" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "groupby test", + "weekStart": "" + } + } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.legacy-ds-ref.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.legacy-ds-ref.json new file mode 100644 index 00000000000..7bb2bc70f81 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.legacy-ds-ref.json @@ -0,0 +1,287 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v1beta1", + "metadata": { + "name": "legacy-ds-ref" + }, + "spec": { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "panels": [ + { + "datasource": "${datasource}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Minimum cluster size" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [10, 10], + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 1 + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 0, + "y": 0 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "editorMode": "code", + "expr": "count by (version) (alloy_build_info{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\"})", + "instant": false, + "legendFormat": "{{version}}", + "range": true, + "refId": "B" + } + ], + "title": "Number of Alloy Instances", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "CPU usage of the Alloy process relative to 1 CPU core.\n\nFor example, 100% means using one entire CPU core.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "Total" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 8, + "y": 0 + }, + "id": 17, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "expr": "rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])\n", + "hide": true, + "instant": false, + "legendFormat": "{{instance}}", + "range": true, + "refId": "A" + }, + { + "datasource": "${datasource}", + "editorMode": "code", + "expr": "sum(rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B" + } + ], + "title": "CPU usage", + "type": "timeseries" + } + ], + "time": { + "from": "now-90m", + "to": "now" + }, + "timezone": "utc", + "title": "Legacy DS Panel Query Ref", + "weekStart": "" + } +} + + \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.panel-target-missing-refid.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.panel-target-missing-refid.json new file mode 100644 index 00000000000..65bf0b136a6 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.panel-target-missing-refid.json @@ -0,0 +1,156 @@ +{ + "apiVersion": "dashboard.grafana.app/v1beta1", + "kind": "Dashboard", + "metadata": { + "name": "ad5vfcn", + "namespace": "default", + "uid": "dlMZZl6GndU8gJLUQSmgZxXBPCNXyXhNBeQJhHXl0r4X", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-11-28T10:14:21Z", + "labels": { + "grafana.app/deprecatedInternalID": "288" + }, + "annotations": { + "grafana.app/createdBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedTimestamp": "2025-11-28T10:15:06Z" + } + }, + "spec": { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 288, + "links": [], + "panels": [ + { + "datasource": { + "type": "testdata", + "uid": "gdev-testdata" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "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": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "datasource": {}, + "queryType": "randomWalk" + }, + { + "datasource": {}, + "queryType": "randomWalk" + } + ], + "title": "New panel", + "type": "timeseries" + } + ], + "preload": false, + "schemaVersion": 42, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Panel ds inheritance ", + "uid": "ad5vfcn", + "version": 2 + }, + "status": {} +} diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.value-mapping-and-overrides.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.value-mapping-and-overrides.json new file mode 100644 index 00000000000..c0a82877ecc --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.value-mapping-and-overrides.json @@ -0,0 +1,603 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v1beta1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + }, + "annotations": {}, + "managedFields": [] + }, + "spec": { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "critical": { + "color": "red", + "index": 0, + "text": "Critical!" + }, + "warning": { + "color": "orange", + "index": 1, + "text": "Warning" + }, + "ok": { + "color": "green", + "index": 2, + "text": "OK" + } + }, + "type": "value" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "targets": [ + { + "expr": "up", + "refId": "A" + } + ], + "title": "ValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "from": 0, + "to": 50, + "result": { + "color": "green", + "index": 0, + "text": "Low" + } + }, + "type": "range" + }, + { + "options": { + "from": 50, + "to": 80, + "result": { + "color": "orange", + "index": 1, + "text": "Medium" + } + }, + "type": "range" + }, + { + "options": { + "from": 80, + "to": 100, + "result": { + "color": "red", + "index": 2, + "text": "High" + } + }, + "type": "range" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "targets": [ + { + "expr": "cpu_usage_percent", + "refId": "A" + } + ], + "title": "RangeMap Example", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "pattern": "/^error.*/", + "result": { + "color": "red", + "index": 0, + "text": "Error" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^warn.*/", + "result": { + "color": "orange", + "index": 1, + "text": "Warning" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^info.*/", + "result": { + "color": "blue", + "index": 2, + "text": "Info" + } + }, + "type": "regex" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "targets": [ + { + "expr": "log_level", + "refId": "A" + } + ], + "title": "RegexMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 0, + "text": "No Data" + } + }, + "type": "special" + }, + { + "options": { + "match": "nan", + "result": { + "color": "gray", + "index": 1, + "text": "Not a Number" + } + }, + "type": "special" + }, + { + "options": { + "match": "null+nan", + "result": { + "color": "gray", + "index": 2, + "text": "N/A" + } + }, + "type": "special" + }, + { + "options": { + "match": "true", + "result": { + "color": "green", + "index": 3, + "text": "Yes" + } + }, + "type": "special" + }, + { + "options": { + "match": "false", + "result": { + "color": "red", + "index": 4, + "text": "No" + } + }, + "type": "special" + }, + { + "options": { + "match": "empty", + "result": { + "color": "gray", + "index": 5, + "text": "Empty" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "blue" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "targets": [ + { + "expr": "some_metric", + "refId": "A" + } + ], + "title": "SpecialValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "success": { + "color": "green", + "index": 0, + "text": "Success" + }, + "failure": { + "color": "red", + "index": 1, + "text": "Failure" + } + }, + "type": "value" + }, + { + "options": { + "from": 0, + "to": 100, + "result": { + "color": "blue", + "index": 2, + "text": "In Range" + } + }, + "type": "range" + }, + { + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "color": "purple", + "index": 3, + "text": "ID Format" + } + }, + "type": "regex" + }, + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 4, + "text": "Missing" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "reducer": "allIsNull", + "op": "gte", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 5, + "targets": [ + { + "expr": "combined_metric", + "refId": "A" + }, + { + "expr": "secondary_metric", + "refId": "B" + } + ], + "title": "Combined Mappings and Overrides Example", + "type": "table" + } + ], + "schemaVersion": 42, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Value Mapping and Overrides Test", + "weekStart": "" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + }, + "access": { + "slug": "value-mapping-test", + "url": "/d/value-mapping-test/value-mapping-and-overrides-test", + "canSave": true, + "canEdit": true, + "canAdmin": true, + "canStar": true, + "canDelete": true, + "annotationsPermissions": { + "dashboard": { + "canAdd": true, + "canEdit": true, + "canDelete": true + }, + "organization": { + "canAdd": true, + "canEdit": true, + "canDelete": true + } + } + } +} diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.variable-conversions.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.variable-conversions.json index ae1ef7cd04e..d6010e5100e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.variable-conversions.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v1beta1.variable-conversions.json @@ -42,7 +42,7 @@ "regex": "", "skipUrlSync": false, "refresh": 1 - }, + }, { "name": "query_var", "type": "query", @@ -81,6 +81,7 @@ "allValue": ".*", "multi": true, "regex": "/.*9090.*/", + "regexApplyTo": "text", "skipUrlSync": false, "refresh": 2, "sort": 1, @@ -107,7 +108,7 @@ }, { "selected": false, - "text": "staging", + "text": "staging", "value": "staging" }, { @@ -335,6 +336,7 @@ "allValue": "*", "multi": true, "regex": "/host[0-9]+/", + "regexApplyTo": "value", "skipUrlSync": false, "refresh": 1, "sort": 2, @@ -354,4 +356,4 @@ }, "links": [] } -} \ No newline at end of file +} diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v2alpha1.ds-data-query.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v2alpha1.ds-data-query.json index a27c33c3239..ac88b83370f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/input/v2alpha1.ds-data-query.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v2alpha1.ds-data-query.json @@ -852,6 +852,194 @@ } } } + }, + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Single Dashboard DS Query", + "description": "Panel with a single -- Dashboard -- datasource query", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "12.1.0-pre", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-8": { + "kind": "Panel", + "spec": { + "id": 8, + "title": "Multiple Dashboard DS Queries", + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 2, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 3, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "C", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "12.1.0-pre", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } } }, "layout": { @@ -914,6 +1102,24 @@ "name": "panel-6" } } + }, + { + "kind": "AutoGridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-7" + } + } + }, + { + "kind": "AutoGridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-8" + } + } } ] } diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.ds-data-query.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.ds-data-query.json index 0c787609714..fad72787d19 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.ds-data-query.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.ds-data-query.json @@ -879,6 +879,200 @@ } } } + }, + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Single Dashboard DS Query", + "description": "Panel with a single -- Dashboard -- datasource query", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "12.1.0-pre", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-8": { + "kind": "Panel", + "spec": { + "id": 8, + "title": "Multiple Dashboard DS Queries", + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 2, + "withTransforms": true + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 3, + "withTransforms": true + } + }, + "refId": "C", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "12.1.0-pre", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } } }, "layout": { @@ -973,6 +1167,32 @@ "name": "panel-6" } } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 6, + "width": 8, + "height": 3, + "element": { + "kind": "ElementReference", + "name": "panel-7" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 8, + "y": 6, + "width": 8, + "height": 3, + "element": { + "kind": "ElementReference", + "name": "panel-8" + } + } } ] } diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.tab-with-multiple-panels.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.tab-with-multiple-panels.json new file mode 100644 index 00000000000..c2bb49cc5cb --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.tab-with-multiple-panels.json @@ -0,0 +1,715 @@ +{ +"kind": "DashboardWithAccessInfo", +"apiVersion": "dashboard.grafana.app/v2beta1", +"metadata": { + "name": "adt885j", + "namespace": "default", + "uid": "yTWet6JgBjlRIWnqRE9ZOmUycfT0tEkr2mljaln1GWIX", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-12-16T10:44:31Z", + "labels": { + "grafana.app/deprecatedInternalID": "2409" + }, + "annotations": { + "grafana.app/createdBy": "user:u000000001", + "grafana.app/updatedBy": "user:u000000001", + "grafana.app/updatedTimestamp": "2025-12-16T10:51:14Z" + } +}, +"spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true + } + } + ], + "cursorSync": "Off", + "description": "", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Panel1", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "datasource": { + "name": "PD8C576611E62080A" + }, + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "12.4.0-pre", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Panel2", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "12.4.0-pre", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "Panel3", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "12.4.0-pre", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "Panel4", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "12.4.0-pre", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Panel5", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "12.4.0-pre", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "TabsLayout", + "spec": { + "tabs": [ + { + "kind": "TabsLayoutTab", + "spec": { + "title": "Tab1", + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 7, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 7, + "y": 0, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 15, + "y": 0, + "width": 9, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + } + ] + } + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Dashboard with tabs", + "variables": [] +}, +"status": {}, +"access": { + "slug": "dashboard-with-tabs", + "url": "/d/adt885j/dashboard-with-tabs", + "isPublic": false, + "canSave": true, + "canEdit": true, + "canAdmin": true, + "canStar": true, + "canDelete": true, + "annotationsPermissions": { + "dashboard": { + "canAdd": true, + "canEdit": true, + "canDelete": true + }, + "organization": { + "canAdd": true, + "canEdit": true, + "canDelete": true + } + } +} +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.value-mapping-and-overrides.json b/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.value-mapping-and-overrides.json new file mode 100644 index 00000000000..54507dafbea --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/input/v2beta1.value-mapping-and-overrides.json @@ -0,0 +1,864 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v2beta1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "ValueMap Example", + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "up" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "critical": { + "text": "Critical!", + "color": "red", + "index": 0 + }, + "ok": { + "text": "OK", + "color": "green", + "index": 2 + }, + "warning": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "RangeMap Example", + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "cpu_usage_percent" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "gauge", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "range", + "options": { + "from": 0, + "to": 50, + "result": { + "text": "Low", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 50, + "to": 80, + "result": { + "text": "Medium", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "range", + "options": { + "from": 80, + "to": 100, + "result": { + "text": "High", + "color": "red", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "RegexMap Example", + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "log_level" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "regex", + "options": { + "pattern": "/^error.*/", + "result": { + "text": "Error", + "color": "red", + "index": 0 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^warn.*/", + "result": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^info.*/", + "result": { + "text": "Info", + "color": "blue", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "SpecialValueMap Example", + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "some_metric" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "No Data", + "color": "gray", + "index": 0 + } + } + }, + { + "type": "special", + "options": { + "match": "nan", + "result": { + "text": "Not a Number", + "color": "gray", + "index": 1 + } + } + }, + { + "type": "special", + "options": { + "match": "null+nan", + "result": { + "text": "N/A", + "color": "gray", + "index": 2 + } + } + }, + { + "type": "special", + "options": { + "match": "true", + "result": { + "text": "Yes", + "color": "green", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "false", + "result": { + "text": "No", + "color": "red", + "index": 4 + } + } + }, + { + "type": "special", + "options": { + "match": "empty", + "result": { + "text": "Empty", + "color": "gray", + "index": 5 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + } + } + } + } + }, + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Empty Properties Override Example", + "description": "Panel with override that has empty properties array - tests conversion of overrides without any property modifications", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "empty_override_metric" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": {}, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "field_with_empty_override" + }, + "properties": [] + } + ] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Combined Mappings and Overrides Example", + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "combined_metric" + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "secondary_metric" + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "table", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "failure": { + "text": "Failure", + "color": "red", + "index": 1 + }, + "success": { + "text": "Success", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 0, + "to": 100, + "result": { + "text": "In Range", + "color": "blue", + "index": 2 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "text": "ID Format", + "color": "purple", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "Missing", + "color": "gray", + "index": 4 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 16, + "width": 24, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 24, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Value Mapping and Overrides Test", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } + } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2alpha1.json index 7a4a4d2c4b7..669e2e742a6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2alpha1.json @@ -66,7 +66,29 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "thresholds": [ + "20", + "30" + ] + }, + { + "align": "auto", + "thresholds": [ + "200", + "300" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +132,22 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "thresholds": [ + "50", + "75" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +191,22 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "styles": [ + { + "thresholds": [ + "5", + "10", + "15" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -237,5 +289,10 @@ "title": "V10 Table Thresholds Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2beta1.json index 69d75b09dcf..22a36b375a0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v10.table_thresholds.v42.v2beta1.json @@ -69,7 +69,29 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "thresholds": [ + "20", + "30" + ] + }, + { + "align": "auto", + "thresholds": [ + "200", + "300" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +137,22 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "thresholds": [ + "50", + "75" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +198,22 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "styles": [ + { + "thresholds": [ + "5", + "10", + "15" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -244,5 +296,10 @@ "title": "V10 Table Thresholds Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2alpha1.json index f427b5dbcb7..b9007aeab43 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2alpha1.json @@ -66,7 +66,18 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +121,20 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -206,5 +230,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2beta1.json index 8e59bbd21ca..75255794c5c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v11.no-op-migration.v42.v2beta1.json @@ -69,7 +69,18 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +126,20 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -213,5 +237,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2alpha1.json index f55769f82b2..5e69664e182 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2alpha1.json @@ -203,5 +203,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2beta1.json index febee713d97..e3d0bff265d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v12.template-variables.v42.v2beta1.json @@ -216,5 +216,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2alpha1.json index a1ef92d3d50..091b4103636 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2alpha1.json @@ -66,7 +66,20 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 200, + "threshold1Color": "yellow", + "threshold2": 400, + "threshold2Color": "red", + "thresholdLine": true + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +123,20 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 100, + "threshold1Color": "green", + "threshold2": 300, + "threshold2Color": "blue", + "thresholdLine": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +180,18 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 150, + "threshold1Color": "orange", + "thresholdLine": true + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -198,7 +235,25 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 200, + "threshold1Color": "yellow", + "thresholdLine": false + }, + "thresholds": [ + { + "color": "purple", + "colorMode": "custom", + "value": 50 + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -242,7 +297,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -351,5 +411,10 @@ "title": "V13 Graph Thresholds Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2beta1.json index a41d04804b7..0fdbbd1990b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.graph_thresholds.v42.v2beta1.json @@ -69,7 +69,20 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 200, + "threshold1Color": "yellow", + "threshold2": 400, + "threshold2Color": "red", + "thresholdLine": true + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +128,20 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 100, + "threshold1Color": "green", + "threshold2": 300, + "threshold2Color": "blue", + "thresholdLine": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +187,18 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 150, + "threshold1Color": "orange", + "thresholdLine": true + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -207,7 +244,25 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "threshold1": 200, + "threshold1Color": "yellow", + "thresholdLine": false + }, + "thresholds": [ + { + "color": "purple", + "colorMode": "custom", + "value": 50 + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -253,7 +308,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -362,5 +422,10 @@ "title": "V13 Graph Thresholds Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2alpha1.json index 3edc16edae6..b2673944cb7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2alpha1.json @@ -72,7 +72,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -129,5 +134,10 @@ "title": "Dashboard with minimal graph panel settings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2beta1.json index 8e18ac60c4d..1b8e98bafc0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v13.minimal_graph_config.v42.v2beta1.json @@ -75,7 +75,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -132,5 +137,10 @@ "title": "Dashboard with minimal graph panel settings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2alpha1.json index e4a62f00bc7..5a00a12baa3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2alpha1.json @@ -68,7 +68,18 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -114,7 +125,20 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "max": 100, + "min": 0, + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -210,5 +234,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2beta1.json index 975fc24c969..9251f743242 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v14.shared_crosshair_to_graph_tooltip.v42.v2beta1.json @@ -71,7 +71,18 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -119,7 +130,20 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "max": 100, + "min": 0, + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -217,5 +241,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v0alpha1.json index 6c259253e55..35cc948844c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v0alpha1.json @@ -743,7 +743,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": true, "label": "cluster", @@ -764,7 +766,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": false, "label": "namespace", diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2alpha1.json index decdff12902..26945033c4c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2alpha1.json @@ -961,8 +961,12 @@ "hide": "dontHide", "refresh": "onDashboardLoad", "skipUrlSync": false, + "datasource": { + "type": "", + "uid": "$datasource" + }, "query": { - "kind": "prometheus", + "kind": "", "spec": { "__legacyStringValue": "label_values(up, job)" } @@ -988,8 +992,12 @@ "hide": "dontHide", "refresh": "onDashboardLoad", "skipUrlSync": false, + "datasource": { + "type": "", + "uid": "$datasource" + }, "query": { - "kind": "prometheus", + "kind": "", "spec": { "__legacyStringValue": "label_values(up{job=~\"$cluster\"}, instance)" } @@ -1004,5 +1012,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2beta1.json index 9db5193d5af..344b0ef564a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.mimir_rollout_debugging.v42.v2beta1.json @@ -978,8 +978,11 @@ "skipUrlSync": false, "query": { "kind": "DataQuery", - "group": "prometheus", + "group": "", "version": "v0", + "datasource": { + "name": "$datasource" + }, "spec": { "__legacyStringValue": "label_values(up, job)" } @@ -1007,8 +1010,11 @@ "skipUrlSync": false, "query": { "kind": "DataQuery", - "group": "prometheus", + "group": "", "version": "v0", + "datasource": { + "name": "$datasource" + }, "spec": { "__legacyStringValue": "label_values(up{job=~\"$cluster\"}, instance)" } @@ -1023,5 +1029,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2alpha1.json index 347556eb45d..551348d7852 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2alpha1.json @@ -83,7 +83,18 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -127,7 +138,20 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -223,5 +247,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2beta1.json index 756f4a76074..c6ab962de2f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v15.no-op-migration.v42.v2beta1.json @@ -87,7 +87,18 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -133,7 +144,20 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -231,5 +255,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2alpha1.json index 1bf45848829..4c21c63a66a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2alpha1.json @@ -1455,5 +1455,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2beta1.json index d7f5fd82659..684b7b0f564 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.empty-rows-and-panels-array.v42.v2beta1.json @@ -1481,5 +1481,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2alpha1.json index 6cf8402f377..c4198fa24b9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2alpha1.json @@ -66,7 +66,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +115,14 @@ "kind": "logs", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "logs", + "originalOptions": { + "height": 100 + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +166,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -198,7 +215,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -254,7 +276,14 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "height": 200 + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -282,7 +311,14 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "height": 200 + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -719,5 +755,10 @@ "title": "V16 Grid Layout Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2beta1.json index 2a6622f27a4..578e9d707ad 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.grid_layout_upgrade.v42.v2beta1.json @@ -69,7 +69,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +120,14 @@ "group": "logs", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "logs", + "originalOptions": { + "height": 100 + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +173,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -207,7 +224,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -265,7 +287,14 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "height": 200 + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -294,7 +323,14 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "height": 200 + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -739,5 +775,10 @@ "title": "V16 Grid Layout Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2alpha1.json index 221b01ffec5..52c19734101 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2alpha1.json @@ -1655,5 +1655,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2beta1.json index 7c05e2ab74c..49e7fb1d9e7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v16.span_zero_demo.v42.v2beta1.json @@ -1707,5 +1707,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2alpha1.json index aa9017f0720..ecc7830b8fa 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2alpha1.json @@ -66,7 +66,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +115,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +164,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -242,7 +257,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -374,7 +394,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -462,7 +487,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -636,5 +666,10 @@ "title": "V17 MinSpan to MaxPerRow Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2beta1.json index 697c0dadaac..ce68572f0d2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v17.minspan_to_maxperrow.v42.v2beta1.json @@ -69,7 +69,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +120,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +171,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -253,7 +268,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -391,7 +411,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -483,7 +508,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -657,5 +687,10 @@ "title": "V17 MinSpan to MaxPerRow Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2alpha1.json index f154e2e2679..55f7729fc1a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2alpha1.json @@ -288,6 +288,10 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "legend": { "show": true, "showLegend": true @@ -401,5 +405,10 @@ "title": "V18 Gauge Options Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2beta1.json index 6d1528a868a..758bdfad09e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v18.gauge_options.v42.v2beta1.json @@ -299,6 +299,10 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "legend": { "show": true, "showLegend": true @@ -412,5 +416,10 @@ "title": "V18 Gauge Options Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2alpha1.json index e51fc93636a..596bd229b79 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2alpha1.json @@ -71,7 +71,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -312,7 +317,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -434,5 +444,10 @@ "title": "V19 Panel Links Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2beta1.json index 0dbf12ef898..1302e17c7f3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v19.panel_links.v42.v2beta1.json @@ -74,7 +74,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -325,7 +330,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -447,5 +457,10 @@ "title": "V19 Panel Links Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2alpha1.json index 129ba30c694..d30c3ce7923 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2alpha1.json @@ -68,7 +68,20 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graphite", + "originalOptions": { + "grid": { + "max": 100, + "min": 0 + }, + "legend": true, + "y2_format": "short", + "y_format": "percent" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -114,7 +127,18 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "min": 0 + }, + "legend": false, + "y_format": "bytes" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -158,7 +182,20 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table", + "originalOptions": { + "grid": { + "max": 100, + "min": 0 + }, + "legend": true, + "y2_format": "bytes", + "y_format": "short" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -204,7 +241,15 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graphite", + "originalOptions": { + "legend": true, + "y2_format": "Bps" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -354,5 +399,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2beta1.json index 0c80ae34850..6a02d64f5b2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v2.panels-and-services.v42.v2beta1.json @@ -71,7 +71,20 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graphite", + "originalOptions": { + "grid": { + "max": 100, + "min": 0 + }, + "legend": true, + "y2_format": "short", + "y_format": "percent" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -119,7 +132,18 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "grid": { + "min": 0 + }, + "legend": false, + "y_format": "bytes" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -165,7 +189,20 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table", + "originalOptions": { + "grid": { + "max": 100, + "min": 0 + }, + "legend": true, + "y2_format": "bytes", + "y_format": "short" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -213,7 +250,15 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graphite", + "originalOptions": { + "legend": true, + "y2_format": "Bps" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -365,5 +410,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2alpha1.json index 95d3f1d8834..1e077553a81 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2alpha1.json @@ -426,5 +426,10 @@ "title": "V20 Variable Syntax Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2beta1.json index f5c9e157c75..13327bcd9f6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v20.variable_syntax_links.v42.v2beta1.json @@ -437,5 +437,10 @@ "title": "V20 Variable Syntax Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2alpha1.json index 0b2251f0dca..a93d077fef3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2alpha1.json @@ -181,6 +181,10 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "dataLinks": [ { "title": "Graph Data Link", @@ -401,5 +405,10 @@ "title": "V21 Data Links Series to Field Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2beta1.json index 8c9808adf32..6244177502b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v21.data_links_series_to_field.v42.v2beta1.json @@ -188,6 +188,10 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "dataLinks": [ { "title": "Graph Data Link", @@ -412,5 +416,10 @@ "title": "V21 Data Links Series to Field Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2alpha1.json index dd03601b0ac..10c570651e5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2alpha1.json @@ -66,7 +66,25 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "pattern": "Time", + "type": "number" + }, + { + "align": "auto", + "pattern": "Value", + "type": "string" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -123,5 +141,10 @@ "title": "V22 Table Panel Styles Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2beta1.json index fd3dc0b587b..8c7d86f1d86 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v22.table_panel_align.v42.v2beta1.json @@ -69,7 +69,25 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "pattern": "Time", + "type": "number" + }, + { + "align": "auto", + "pattern": "Value", + "type": "string" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -126,5 +144,10 @@ "title": "V22 Table Panel Styles Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2alpha1.json index a40797444f4..3e93dbc7a66 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2alpha1.json @@ -374,5 +374,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2beta1.json index a97d9a51e2f..7286db67bf2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v23.multi_variable_alignment.v42.v2beta1.json @@ -391,5 +391,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2alpha1.json index c9dd5bffa51..6fa76798215 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2alpha1.json @@ -81,7 +81,29 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "legend": true, + "styles": [ + { + "colors": [ + "red", + "yellow", + "green" + ], + "pattern": "/.*/", + "thresholds": [ + "10", + "20", + "30" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -125,7 +147,31 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "center", + "pattern": "/.*/" + }, + { + "align": "left", + "pattern": "LeftColumn" + }, + { + "align": "right", + "pattern": "RightColumn" + }, + { + "align": "auto", + "pattern": "AutoColumn" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -169,7 +215,35 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + }, + { + "alias": "Exact Match", + "pattern": "ExactColumnName" + }, + { + "alias": "Regex Match", + "pattern": "/Regex.*Pattern/" + }, + { + "alias": "Start Pattern", + "pattern": "/^Start/" + }, + { + "alias": "End Pattern", + "pattern": "/End$/" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -213,7 +287,37 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + }, + { + "link": true, + "linkTargetBlank": true, + "linkTooltip": "Click to view details", + "linkUrl": "http://example.com/with-tooltip", + "pattern": "LinkWithTooltip" + }, + { + "link": true, + "linkTargetBlank": false, + "linkUrl": "http://example.com/no-tooltip", + "pattern": "LinkWithoutTooltip" + }, + { + "link": true, + "linkUrl": "http://example.com/minimal", + "pattern": "LinkMinimal" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -257,7 +361,37 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + }, + { + "alias": "ISO Date", + "dateFormat": "YYYY-MM-DD", + "pattern": "DateISO", + "type": "date" + }, + { + "alias": "Full DateTime", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "DateTime", + "type": "date" + }, + { + "alias": "Time Only", + "dateFormat": "HH:mm:ss", + "pattern": "TimeOnly", + "type": "date" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -301,7 +435,29 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table", + "originalOptions": { + "styles": [ + { + "colors": [ + "red", + "yellow", + "green" + ], + "pattern": "/.*/", + "thresholds": [ + "10", + "20" + ], + "unit": "short" + } + ], + "table": "table2" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -389,7 +545,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -433,7 +594,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -477,7 +643,57 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "center", + "colorMode": "cell", + "colors": [ + "green", + "yellow", + "red" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + "100", + "500" + ], + "unit": "bytes" + }, + { + "alias": "Current Status", + "align": "left", + "colorMode": "value", + "decimals": 0, + "pattern": "Status", + "unit": "short" + }, + { + "colorMode": "row", + "link": true, + "linkTargetBlank": true, + "linkTooltip": "View error details", + "linkUrl": "http://example.com/errors", + "pattern": "/Error.*/" + }, + { + "alias": "Timestamp", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "pattern": "Hidden", + "type": "hidden" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -521,7 +737,47 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Maximum", + "value": "max" + }, + { + "text": "Minimum", + "value": "min" + }, + { + "text": "Total", + "value": "total" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Count", + "value": "count" + } + ], + "styles": [ + { + "decimals": 1, + "pattern": "/.*/", + "unit": "percent" + } + ], + "transform": "timeseries_aggregations" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -565,7 +821,20 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + } + ], + "transform": "timeseries_to_rows" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -609,7 +878,20 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "bytes" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -653,7 +935,20 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "pattern": "/.*/" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -712,7 +1007,20 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + } + ], + "transform": "timeseries_to_rows" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -756,7 +1064,29 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "colors": [ + "green", + "yellow", + "orange", + "red" + ], + "pattern": "/.*/", + "thresholds": [ + 10, + "20", + 30.5 + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -800,7 +1130,31 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "colorMode": "cell", + "pattern": "/.*/" + }, + { + "colorMode": "cell", + "pattern": "CellColumn" + }, + { + "colorMode": "row", + "pattern": "RowColumn" + }, + { + "colorMode": "value", + "pattern": "ValueColumn" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1065,5 +1419,10 @@ "title": "No Title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2beta1.json index 3d74b493b8e..9ae87fe0f32 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v24.table-angular.v42.v2beta1.json @@ -85,7 +85,29 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "legend": true, + "styles": [ + { + "colors": [ + "red", + "yellow", + "green" + ], + "pattern": "/.*/", + "thresholds": [ + "10", + "20", + "30" + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -131,7 +153,31 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "center", + "pattern": "/.*/" + }, + { + "align": "left", + "pattern": "LeftColumn" + }, + { + "align": "right", + "pattern": "RightColumn" + }, + { + "align": "auto", + "pattern": "AutoColumn" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -177,7 +223,35 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + }, + { + "alias": "Exact Match", + "pattern": "ExactColumnName" + }, + { + "alias": "Regex Match", + "pattern": "/Regex.*Pattern/" + }, + { + "alias": "Start Pattern", + "pattern": "/^Start/" + }, + { + "alias": "End Pattern", + "pattern": "/End$/" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -223,7 +297,37 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + }, + { + "link": true, + "linkTargetBlank": true, + "linkTooltip": "Click to view details", + "linkUrl": "http://example.com/with-tooltip", + "pattern": "LinkWithTooltip" + }, + { + "link": true, + "linkTargetBlank": false, + "linkUrl": "http://example.com/no-tooltip", + "pattern": "LinkWithoutTooltip" + }, + { + "link": true, + "linkUrl": "http://example.com/minimal", + "pattern": "LinkMinimal" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -269,7 +373,37 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + }, + { + "alias": "ISO Date", + "dateFormat": "YYYY-MM-DD", + "pattern": "DateISO", + "type": "date" + }, + { + "alias": "Full DateTime", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "DateTime", + "type": "date" + }, + { + "alias": "Time Only", + "dateFormat": "HH:mm:ss", + "pattern": "TimeOnly", + "type": "date" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -315,7 +449,29 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table", + "originalOptions": { + "styles": [ + { + "colors": [ + "red", + "yellow", + "green" + ], + "pattern": "/.*/", + "thresholds": [ + "10", + "20" + ], + "unit": "short" + } + ], + "table": "table2" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -407,7 +563,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -453,7 +614,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -499,7 +665,57 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "center", + "colorMode": "cell", + "colors": [ + "green", + "yellow", + "red" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [ + "100", + "500" + ], + "unit": "bytes" + }, + { + "alias": "Current Status", + "align": "left", + "colorMode": "value", + "decimals": 0, + "pattern": "Status", + "unit": "short" + }, + { + "colorMode": "row", + "link": true, + "linkTargetBlank": true, + "linkTooltip": "View error details", + "linkUrl": "http://example.com/errors", + "pattern": "/Error.*/" + }, + { + "alias": "Timestamp", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "pattern": "Hidden", + "type": "hidden" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -545,7 +761,47 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Maximum", + "value": "max" + }, + { + "text": "Minimum", + "value": "min" + }, + { + "text": "Total", + "value": "total" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Count", + "value": "count" + } + ], + "styles": [ + { + "decimals": 1, + "pattern": "/.*/", + "unit": "percent" + } + ], + "transform": "timeseries_aggregations" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -591,7 +847,20 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + } + ], + "transform": "timeseries_to_rows" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -637,7 +906,20 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "bytes" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -683,7 +965,20 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "align": "auto", + "pattern": "/.*/" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -744,7 +1039,20 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "pattern": "/.*/", + "unit": "short" + } + ], + "transform": "timeseries_to_rows" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -790,7 +1098,29 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "colors": [ + "green", + "yellow", + "orange", + "red" + ], + "pattern": "/.*/", + "thresholds": [ + 10, + "20", + 30.5 + ] + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -836,7 +1166,31 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "styles": [ + { + "colorMode": "cell", + "pattern": "/.*/" + }, + { + "colorMode": "cell", + "pattern": "CellColumn" + }, + { + "colorMode": "row", + "pattern": "RowColumn" + }, + { + "colorMode": "value", + "pattern": "ValueColumn" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1101,5 +1455,10 @@ "title": "No Title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2alpha1.json index 3375a6bffe4..618d1193a1c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2alpha1.json @@ -123,7 +123,18 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -217,5 +228,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2beta1.json index b873fdea3a3..7fd6cdec538 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v25.no-op-migration.v42.v2beta1.json @@ -130,7 +130,18 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -226,5 +237,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2alpha1.json index a135614baba..c7298296064 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2alpha1.json @@ -110,7 +110,15 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "# Angular Text Panel\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text\n\n", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -240,5 +248,10 @@ "title": "No Title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2beta1.json index 378ae69f16a..db2cfcb916e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v26.text2_to_text.v42.v2beta1.json @@ -115,7 +115,15 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "# Angular Text Panel\n# $constant\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n## $text\n\n", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -247,5 +255,10 @@ "title": "No Title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2alpha1.json index 51cdcba85c1..bab8c53ac6a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2alpha1.json @@ -66,7 +66,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -94,7 +99,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -207,5 +217,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2beta1.json index 3fdcd01a27c..79dab4989d1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v27.repeated_panels_and_constant_variable.v42.v2beta1.json @@ -69,7 +69,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -98,7 +103,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -211,5 +221,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2alpha1.json index 54384f8dc06..75831381989 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2alpha1.json @@ -131,5 +131,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2beta1.json index 6626b919137..e79b7d1f7d7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.remove_variable_properties.v42.v2beta1.json @@ -134,5 +134,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2alpha1.json index 82fc46be585..14e59bfc9bc 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2alpha1.json @@ -81,7 +81,24 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -125,7 +142,28 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "gauge": { + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "grid": { + "max": 10, + "min": 1 + }, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -184,7 +222,47 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + } + ], + "thresholds": "10,20,30", + "valueMaps": [ + { + "op": "=", + "text": "test", + "value": "20" + }, + { + "op": "=", + "text": "test1", + "value": "30" + }, + { + "op": "=", + "text": "50", + "value": "40" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -393,5 +471,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2beta1.json index 4eff500bef6..4f376187bba 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_and_variable_properties.v42.v2beta1.json @@ -85,7 +85,24 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -131,7 +148,28 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "gauge": { + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "grid": { + "max": 10, + "min": 1 + }, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -193,7 +231,47 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + } + ], + "thresholds": "10,20,30", + "valueMaps": [ + { + "op": "=", + "text": "test", + "value": "20" + }, + { + "op": "=", + "text": "test1", + "value": "30" + }, + { + "op": "=", + "text": "50", + "value": "40" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -406,5 +484,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2alpha1.json index 0873ad2190c..195ceebb6cc 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2alpha1.json @@ -81,7 +81,24 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -140,7 +157,24 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "thresholds": "" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -184,7 +218,28 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "gauge": { + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "grid": { + "max": 10, + "min": 1 + }, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -243,7 +298,47 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + } + ], + "thresholds": "10,20,30", + "valueMaps": [ + { + "op": "=", + "text": "test", + "value": "20" + }, + { + "op": "=", + "text": "test1", + "value": "30" + }, + { + "op": "=", + "text": "50", + "value": "40" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -289,7 +384,68 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-singlestat-panel", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -622,5 +778,10 @@ "title": "V28 Singlestat and Variable Properties Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2beta1.json index 2b7d27024c6..fb221254e90 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v28.singlestat_migration.v42.v2beta1.json @@ -85,7 +85,24 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -147,7 +164,24 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "thresholds": "" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -193,7 +227,28 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "gauge": { + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "grid": { + "max": 10, + "min": 1 + }, + "thresholds": "10,20,30" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -255,7 +310,47 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colors": [ + "#FF0000", + "green", + "orange" + ], + "grid": { + "max": 10, + "min": 1 + }, + "legend": true, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + } + ], + "thresholds": "10,20,30", + "valueMaps": [ + { + "op": "=", + "text": "test", + "value": "20" + }, + { + "op": "=", + "text": "test1", + "value": "30" + }, + { + "op": "=", + "text": "50", + "value": "40" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -303,7 +398,68 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-singlestat-panel", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -642,5 +798,10 @@ "title": "V28 Singlestat and Variable Properties Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2alpha1.json index 2688367b33b..5a096f20011 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2alpha1.json @@ -435,5 +435,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2beta1.json index 8e57483ceb4..270c6912485 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v29.query_variables_refresh_and_options.v42.v2beta1.json @@ -458,5 +458,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2alpha1.json index db33eea5445..112dae69255 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2alpha1.json @@ -294,5 +294,10 @@ "title": "V3 No-Op Migration - but tests ensuring panel IDs are unique", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2beta1.json index 4a38725abc3..0a3a97926b8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v3.no-op.v42.v2beta1.json @@ -303,5 +303,10 @@ "title": "V3 No-Op Migration - but tests ensuring panel IDs are unique", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2alpha1.json index 60334f9ffb1..40e4072138c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2alpha1.json @@ -280,6 +280,10 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "tooltip": { "mode": "single" } @@ -530,7 +534,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -689,5 +693,10 @@ "title": "V30 Value Mappings and Tooltip Options Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2beta1.json index 6848d2d1714..9f5630252bf 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v30.value_mappings_and_tooltip_options.v42.v2beta1.json @@ -289,6 +289,10 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "tooltip": { "mode": "single" } @@ -546,7 +550,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -705,5 +709,10 @@ "title": "V30 Value Mappings and Tooltip Options Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2alpha1.json index ac34174bfcb..6fe0fcc67c8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2alpha1.json @@ -669,5 +669,10 @@ "title": "V31 LabelsToFields Merge Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2beta1.json index d7f0684597c..5ca1fbff96c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v31.labels_to_fields_merge.v42.v2beta1.json @@ -684,5 +684,10 @@ "title": "V31 LabelsToFields Merge Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2alpha1.json index 3c58166f6c4..369db4327b7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2alpha1.json @@ -144,7 +144,18 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -310,5 +321,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2beta1.json index 1611cea2464..1fd5d1638ec 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v32.no_op_migration.v42.v2beta1.json @@ -151,7 +151,18 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "yAxes": [ + { + "show": true + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -320,5 +331,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2alpha1.json index d41d2d7bda3..b21c071f750 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2alpha1.json @@ -345,7 +345,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -548,7 +553,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -720,5 +725,10 @@ "title": "V33 Panel Datasource Name to Ref Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2beta1.json index fbb8d83b728..c541c51dc42 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v33.panel_ds_name_to_ref.v42.v2beta1.json @@ -361,7 +361,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -574,7 +579,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -746,5 +751,10 @@ "title": "V33 Panel Datasource Name to Ref Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2alpha1.json index ad69702a739..bc705379491 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2alpha1.json @@ -1663,7 +1663,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -1900,5 +1900,10 @@ "title": "CloudWatch Multiple Statistics Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2beta1.json index 79ee3db369e..329e10bcd42 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v34.multiple_stats_cloudwatch.v42.v2beta1.json @@ -1727,7 +1727,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -1964,5 +1964,10 @@ "title": "CloudWatch Multiple Statistics Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2alpha1.json index c06dd85bb25..cbb59009f10 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2alpha1.json @@ -595,5 +595,10 @@ "title": "X-Axis Visibility Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2beta1.json index f9be2a6cee1..fde3ba9c006 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v35.ensure_x_axis_visibility.v42.v2beta1.json @@ -612,5 +612,10 @@ "title": "X-Axis Visibility Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2alpha1.json index 474b22d4ffb..97a0dd7d19c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2alpha1.json @@ -1029,5 +1029,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2beta1.json index 6465fae7ed0..24c49f553ae 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v36.ds_name_to_ref.v42.v2beta1.json @@ -1065,5 +1065,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2alpha1.json index eb254828d3e..7dc1d5c7069 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2alpha1.json @@ -111,6 +111,10 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "legend": { "displayMode": "list", "showLegend": false @@ -207,6 +211,10 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "legend": { "displayMode": "list", "showLegend": false @@ -629,5 +637,10 @@ "title": "V37 Legend Normalization Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2beta1.json index 2803cc68947..ba78f73005d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v37.legend_normalization.v42.v2beta1.json @@ -115,6 +115,10 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "legend": { "displayMode": "list", "showLegend": false @@ -214,6 +218,10 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + }, "legend": { "displayMode": "list", "showLegend": false @@ -642,5 +650,10 @@ "title": "V37 Legend Normalization Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2alpha1.json index 92f6ec2ef8e..89dd54e3bf6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2alpha1.json @@ -443,7 +443,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -659,5 +664,10 @@ "title": "V38 Table Migration Comprehensive Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2beta1.json index 493b6147404..546c73663d6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.table_displaymode_comprehensive.v42.v2beta1.json @@ -455,7 +455,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -671,5 +676,10 @@ "title": "V38 Table Migration Comprehensive Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2alpha1.json index a1fb5ca81af..92dce415c0d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2alpha1.json @@ -443,7 +443,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -659,5 +664,10 @@ "title": "V38 Table Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2beta1.json index 81cc875df07..7d89cc8bbdd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v38.timeseries_table_display_mode.v42.v2beta1.json @@ -455,7 +455,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -671,5 +676,10 @@ "title": "V38 Table Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2alpha1.json index 37eb51fbdff..8d382676f16 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2alpha1.json @@ -217,7 +217,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -396,7 +401,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -586,5 +596,10 @@ "title": "V39 TimeSeriesTable Transformation Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2beta1.json index 3b56960e026..fe92c7f9537 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v39.transform_timeseries_table.v42.v2beta1.json @@ -222,7 +222,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -406,7 +411,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -596,5 +606,10 @@ "title": "V39 TimeSeriesTable Transformation Migration Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2alpha1.json index e6701e601c7..45615b7ae44 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2alpha1.json @@ -66,7 +66,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +115,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +164,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -237,5 +252,10 @@ "title": "V4 No-Op Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2beta1.json index b6d1aa7d200..3a7e5420f11 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v4.no-op.v42.v2beta1.json @@ -69,7 +69,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +120,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +171,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -244,5 +259,10 @@ "title": "V4 No-Op Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2alpha1.json index 10f6bbf20f4..40df255245e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "Empty String Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2beta1.json index a6cabe62d43..44136818b17 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_empty_string.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "Empty String Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2alpha1.json index 13a901e94af..e149f9f6a45 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "Boolean False Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2beta1.json index 7b5f900ef36..0499fbc7328 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_false.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "Boolean False Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2alpha1.json index 04b94fc3919..95b61ef4e22 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "Refresh Not Set Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2beta1.json index 1f09949f995..93ce85b17e1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_not_set.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "Refresh Not Set Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2alpha1.json index 103fe15fdf3..fd250ce03c6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "Numeric Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2beta1.json index 6904267e72b..f81e1b004e9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_numeric.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "Numeric Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2alpha1.json index 9fe42b778dd..94fa361257d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "String Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2beta1.json index b1bd81269c1..f8818a9dbf3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_string.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "String Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2alpha1.json index 3524796f0aa..bd9f897d313 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "Boolean Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2beta1.json index 76eea7dbbdc..eecd119a617 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v40.refresh_true.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "Boolean Refresh Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2alpha1.json index 9036e54f22d..ed1ea8dc001 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "No Time Picker Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2beta1.json index 54e2cfeef43..6b3b49c11e5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.no_time_picker.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "No Time Picker Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2alpha1.json index 78e27ac4411..2806b7c6d8d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "Time Picker No Time Options Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2beta1.json index 52de1909de4..5b9595d8f74 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_no_time_options.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "Time Picker No Time Options Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2alpha1.json index 8115f687203..a48695c53ec 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2alpha1.json @@ -64,5 +64,10 @@ "title": "Time Picker Time Options Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2beta1.json index 9dffb1fc27e..3f31b897bf0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v41.time_picker_time_options.v42.v2beta1.json @@ -65,5 +65,10 @@ "title": "Time Picker Time Options Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2alpha1.json index ee97abbd7e2..6aa423b4431 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2alpha1.json @@ -123,5 +123,10 @@ "title": "v42 Migration Test - Harky Must", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2beta1.json index 3d267c3135b..79648901fc2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.harky_must.v42.v2beta1.json @@ -125,5 +125,10 @@ "title": "v42 Migration Test - Harky Must", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2alpha1.json index d231c6561ad..e019782a68b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2alpha1.json @@ -94,7 +94,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [ @@ -328,7 +333,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -461,5 +466,10 @@ "title": "v42 Migration Test - HideFrom Tooltip", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2beta1.json index a1e187676a5..f97c257c251 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v42.hidefrom_tooltip.v42.v2beta1.json @@ -97,7 +97,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [ @@ -335,7 +340,7 @@ "kind": "RowsLayoutRow", "spec": { "title": "", - "collapse": true, + "collapse": false, "hideHeader": true, "layout": { "kind": "GridLayout", @@ -468,5 +473,10 @@ "title": "v42 Migration Test - HideFrom Tooltip", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2alpha1.json index 3c5f977cf19..a1fc7ad4752 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2alpha1.json @@ -66,7 +66,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +115,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +164,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -237,5 +252,10 @@ "title": "V5 No-Op Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2beta1.json index 10544c3c0fe..860ab47b3ea 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v5.no-op.v42.v2beta1.json @@ -69,7 +69,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +120,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +171,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -244,5 +259,10 @@ "title": "V5 No-Op Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2alpha1.json index 5c98e01c0f0..6ca93a6768a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2alpha1.json @@ -108,7 +108,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +159,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -332,5 +342,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2beta1.json index 19fbf9be88f..0fa353e9a30 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v6.pulldowns_and_templating.v42.v2beta1.json @@ -113,7 +113,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +166,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -344,5 +354,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2alpha1.json index 425516baea9..10b57eb4b69 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2alpha1.json @@ -142,5 +142,10 @@ "title": "No Title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2beta1.json index 72cb9aadb9b..252a510f233 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v7.timepicker.v42.v2beta1.json @@ -146,5 +146,10 @@ "title": "No Title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2alpha1.json index 0bf433b534a..1bdd08aecf5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2alpha1.json @@ -119,7 +119,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -177,7 +182,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -247,5 +257,10 @@ "title": "V8 InfluxDB Query Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2beta1.json index d8ee1076605..ed5b9515a9f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v8.influxdb_query.v42.v2beta1.json @@ -122,7 +122,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -182,7 +187,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -252,5 +262,10 @@ "title": "V8 InfluxDB Query Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2alpha1.json index 0e4ea43800d..b69579db16b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2alpha1.json @@ -66,7 +66,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -110,7 +115,12 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +164,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -237,5 +252,10 @@ "title": "V9 No-Op Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2beta1.json index 45487aaebb9..2f8f9c79a0b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/migrated_dashboards_output/v1beta1-mig-v9.no-op.v42.v2beta1.json @@ -69,7 +69,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -115,7 +120,12 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +171,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -244,5 +259,10 @@ "title": "V9 No-Op Migration Test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v0alpha1.json index 5a6cebb8a91..e181c66eaf1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v1beta1.json index 122c6772dfe..6c7da8a3864 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v10.table_thresholds.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v0alpha1.json index 0442d15c222..ed6e158988b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v1beta1.json index e1548f77853..dab8e4d166c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v11.no-op-migration.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v0alpha1.json index 7aadfcf8535..0d943be33e1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -93,6 +105,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -115,6 +131,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v1beta1.json index 7f7f61699e5..7d51fccb5f4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.graph_thresholds.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -93,6 +105,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -115,6 +131,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v0alpha1.json index e768e617055..d26aeb546b0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v1beta1.json index 2c88ea03447..1dc3f1743cd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v13.minimal_graph_config.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v0alpha1.json index 6f6b04077da..cefd07bd3b0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -50,6 +54,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v1beta1.json index d83cb315419..765bf5993d3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v14.shared_crosshair_to_graph_tooltip.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -50,6 +54,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v0alpha1.json index cc366a688e3..556e8ee5040 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v0alpha1.json @@ -65,6 +65,9 @@ "type": "row" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Versions running\nShows the versions reported by each running pod.\n\nThe rollout will fail if any pod is not running the expected version.\n\nPods in green are running the expected version, while pods running other versions are shown in orange.\n\n", "fieldConfig": { "defaults": { @@ -185,6 +188,9 @@ "type": "barchart" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Deployment rollout progress\nShows the number of pods for each `Deployment` that match the desired configuration, as a proportion of the desired number of pods.\n\nThe rollout will fail if insufficient pods match the desired configuration for any `Deployment`.\n\nPods in green match the desired configuration, while pods that do not match the desired configuration are shown in orange.\n\n", "fieldConfig": { "defaults": { @@ -286,6 +292,9 @@ "type": "barchart" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### StatefulSet rollout progress\nShows the number of pods for each `StatefulSet` that match the desired configuration, as a proportion of the desired number of pods.\n\nThe rollout will fail if insufficient pods match the desired configuration for any `StatefulSet`.\n\nPods in green match the desired configuration, while pods that do not match the desired configuration are shown in orange.\n\n", "fieldConfig": { "defaults": { @@ -399,6 +408,9 @@ "type": "row" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Aggregator lag\nShows the consumption lag of each aggregator pod.\n\nThis panel may show no data if aggregators are not deployed to this cell.\n\nThe rollout will fail if any pod's consumption lag is both:\n* greater than 30s (red area on graph), and\n* trending upwards compared to 1 minute earlier\n\n", "fieldConfig": { "defaults": { @@ -468,6 +480,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Unhealthy Deployment replicas\nShows the number of unavailable pods for each `Deployment`.\n\nThe rollout will fail if any `Deployment` has an unavailable pod.\n\nBoth this panel and the rollout check ignore any `Deployment`s that require spot nodes, as these are expected to be unavailable from time to time.\n\n`Deployment`s shown in green do not have any unavailable pods, while `Deployment`s shown in orange have one or more unavailable pods.\n\n", "fieldConfig": { "defaults": { @@ -569,6 +584,9 @@ "type": "barchart" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Unhealthy StatefulSet replicas\nShows the number of pods for each `StatefulSet` that are not ready.\n\nThe rollout will fail if any `StatefulSet` has fewer ready pods than requested.\n\nBoth this panel and the rollout check ignore any `StatefulSets`s that require spot nodes, as these are expected to be unavailable from time to time.\n\n`StatefulSets`s shown in green do not have any pods that are not ready, while `StatefulSet`s shown in orange have one or more pods that are not ready.\n\n", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v1beta1.json index cbe61ee0ed7..0b50d42fbe7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.mimir_rollout_debugging.v1beta1.json @@ -65,6 +65,9 @@ "type": "row" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Versions running\nShows the versions reported by each running pod.\n\nThe rollout will fail if any pod is not running the expected version.\n\nPods in green are running the expected version, while pods running other versions are shown in orange.\n\n", "fieldConfig": { "defaults": { @@ -185,6 +188,9 @@ "type": "barchart" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Deployment rollout progress\nShows the number of pods for each `Deployment` that match the desired configuration, as a proportion of the desired number of pods.\n\nThe rollout will fail if insufficient pods match the desired configuration for any `Deployment`.\n\nPods in green match the desired configuration, while pods that do not match the desired configuration are shown in orange.\n\n", "fieldConfig": { "defaults": { @@ -286,6 +292,9 @@ "type": "barchart" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### StatefulSet rollout progress\nShows the number of pods for each `StatefulSet` that match the desired configuration, as a proportion of the desired number of pods.\n\nThe rollout will fail if insufficient pods match the desired configuration for any `StatefulSet`.\n\nPods in green match the desired configuration, while pods that do not match the desired configuration are shown in orange.\n\n", "fieldConfig": { "defaults": { @@ -399,6 +408,9 @@ "type": "row" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Aggregator lag\nShows the consumption lag of each aggregator pod.\n\nThis panel may show no data if aggregators are not deployed to this cell.\n\nThe rollout will fail if any pod's consumption lag is both:\n* greater than 30s (red area on graph), and\n* trending upwards compared to 1 minute earlier\n\n", "fieldConfig": { "defaults": { @@ -468,6 +480,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Unhealthy Deployment replicas\nShows the number of unavailable pods for each `Deployment`.\n\nThe rollout will fail if any `Deployment` has an unavailable pod.\n\nBoth this panel and the rollout check ignore any `Deployment`s that require spot nodes, as these are expected to be unavailable from time to time.\n\n`Deployment`s shown in green do not have any unavailable pods, while `Deployment`s shown in orange have one or more unavailable pods.\n\n", "fieldConfig": { "defaults": { @@ -569,6 +584,9 @@ "type": "barchart" }, { + "datasource": { + "uid": "$datasource" + }, "description": "### Unhealthy StatefulSet replicas\nShows the number of pods for each `StatefulSet` that are not ready.\n\nThe rollout will fail if any `StatefulSet` has fewer ready pods than requested.\n\nBoth this panel and the rollout check ignore any `StatefulSets`s that require spot nodes, as these are expected to be unavailable from time to time.\n\n`StatefulSets`s shown in green do not have any pods that are not ready, while `StatefulSet`s shown in orange have one or more pods that are not ready.\n\n", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v0alpha1.json index dd68f978199..720fff258cc 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v0alpha1.json @@ -37,6 +37,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -59,6 +63,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v1beta1.json index 6efa2fd1853..370eafaad0c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v15.no-op-migration.v1beta1.json @@ -37,6 +37,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -59,6 +63,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v0alpha1.json index 3d8d1b11ad3..99a2102204c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v0alpha1.json @@ -44,6 +44,9 @@ "liveNow": false, "panels": [ { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample metric showing connection count.", "fieldConfig": { "defaults": { @@ -134,6 +137,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample counter metric.", "fieldConfig": { "defaults": { @@ -224,6 +230,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample error metric.", "fieldConfig": { "defaults": { @@ -314,6 +323,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample event rate metric.", "fieldConfig": { "defaults": { @@ -404,6 +416,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample resource utilization metric.", "fieldConfig": { "defaults": { @@ -493,6 +508,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample memory allocation metrics.", "fieldConfig": { "defaults": { @@ -593,6 +611,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample utilization percentage.", "fieldConfig": { "defaults": { @@ -662,6 +683,9 @@ "type": "row" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample latency metric for primary operations.", "fieldConfig": { "defaults": { @@ -748,6 +772,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample latency metric for secondary operations.", "fieldConfig": { "defaults": { @@ -834,6 +861,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample expansion events metric.", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v1beta1.json index e93a8eb3132..58f46289f57 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.empty-rows-and-panels-array.v1beta1.json @@ -44,6 +44,9 @@ "liveNow": false, "panels": [ { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample metric showing connection count.", "fieldConfig": { "defaults": { @@ -134,6 +137,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample counter metric.", "fieldConfig": { "defaults": { @@ -224,6 +230,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample error metric.", "fieldConfig": { "defaults": { @@ -314,6 +323,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample event rate metric.", "fieldConfig": { "defaults": { @@ -404,6 +416,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample resource utilization metric.", "fieldConfig": { "defaults": { @@ -493,6 +508,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample memory allocation metrics.", "fieldConfig": { "defaults": { @@ -593,6 +611,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample utilization percentage.", "fieldConfig": { "defaults": { @@ -662,6 +683,9 @@ "type": "row" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample latency metric for primary operations.", "fieldConfig": { "defaults": { @@ -748,6 +772,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample latency metric for secondary operations.", "fieldConfig": { "defaults": { @@ -834,6 +861,9 @@ "type": "timeseries" }, { + "datasource": { + "uid": "${example_datasource}" + }, "description": "Sample expansion events metric.", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v0alpha1.json index 286cc75e2c0..025ec384a0c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v0alpha1.json @@ -39,6 +39,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 12, @@ -61,6 +65,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 12, @@ -151,6 +159,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -173,6 +185,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -195,6 +211,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -229,6 +249,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 16, @@ -251,6 +275,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 8, @@ -286,6 +314,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 24, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v1beta1.json index a4d76abe265..1334aad64b4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.grid_layout_upgrade.v1beta1.json @@ -39,6 +39,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 12, @@ -61,6 +65,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 12, @@ -151,6 +159,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -173,6 +185,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -195,6 +211,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -229,6 +249,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 16, @@ -251,6 +275,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 8, @@ -286,6 +314,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 24, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v0alpha1.json index a57a713ba61..0279b19424c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v0alpha1.json @@ -41,6 +41,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 24, @@ -78,6 +82,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -103,6 +111,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -128,6 +140,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "fieldConfig": { "defaults": { "thresholds": { @@ -174,6 +190,10 @@ "type": "stat" }, { + "datasource": { + "type": "loki", + "uid": "${loki}" + }, "gridPos": { "h": 7, "w": 8, @@ -202,6 +222,10 @@ "type": "logs" }, { + "datasource": { + "type": "loki", + "uid": "${loki}" + }, "gridPos": { "h": 7, "w": 8, @@ -230,6 +254,10 @@ "type": "logs" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -255,6 +283,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Number of concurrent processing threads available for handling operations", "gridPos": { "h": 7, @@ -280,6 +312,10 @@ "type": "stat" }, { + "datasource": { + "type": "tempo", + "uid": "${tempo}" + }, "gridPos": { "h": 7, "w": 8, @@ -324,6 +360,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Histogram showing p99, p95, p50, and p10 percentiles for job processing duration based on number of resources changed", "fieldConfig": { "defaults": { @@ -425,6 +465,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Histogram showing p99, p95, p50, and p10 percentiles for job processing duration based on number of resources changed", "gridPos": { "h": 7, @@ -477,6 +521,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Total number of jobs waiting to be processed", "gridPos": { "h": 7, @@ -502,6 +550,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "fieldConfig": { "defaults": { "unit": "s" @@ -532,6 +584,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "How long a job is in the queue before being picked up", "gridPos": { "h": 7, @@ -584,6 +640,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -609,6 +669,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "gridPos": { "h": 7, "w": 8, @@ -633,6 +697,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "gridPos": { "h": 7, "w": 8, @@ -675,6 +743,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "gridPos": { "h": 7, "w": 8, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v1beta1.json index 61094ee5dbd..5597a468c53 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v16.span_zero_demo.v1beta1.json @@ -41,6 +41,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 24, @@ -78,6 +82,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -103,6 +111,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -128,6 +140,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "fieldConfig": { "defaults": { "thresholds": { @@ -174,6 +190,10 @@ "type": "stat" }, { + "datasource": { + "type": "loki", + "uid": "${loki}" + }, "gridPos": { "h": 7, "w": 8, @@ -202,6 +222,10 @@ "type": "logs" }, { + "datasource": { + "type": "loki", + "uid": "${loki}" + }, "gridPos": { "h": 7, "w": 8, @@ -230,6 +254,10 @@ "type": "logs" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -255,6 +283,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Number of concurrent processing threads available for handling operations", "gridPos": { "h": 7, @@ -280,6 +312,10 @@ "type": "stat" }, { + "datasource": { + "type": "tempo", + "uid": "${tempo}" + }, "gridPos": { "h": 7, "w": 8, @@ -324,6 +360,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Histogram showing p99, p95, p50, and p10 percentiles for job processing duration based on number of resources changed", "fieldConfig": { "defaults": { @@ -425,6 +465,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Histogram showing p99, p95, p50, and p10 percentiles for job processing duration based on number of resources changed", "gridPos": { "h": 7, @@ -477,6 +521,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "Total number of jobs waiting to be processed", "gridPos": { "h": 7, @@ -502,6 +550,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "fieldConfig": { "defaults": { "unit": "s" @@ -532,6 +584,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "description": "How long a job is in the queue before being picked up", "gridPos": { "h": 7, @@ -584,6 +640,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 7, "w": 8, @@ -609,6 +669,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "gridPos": { "h": 7, "w": 8, @@ -633,6 +697,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "gridPos": { "h": 7, "w": 8, @@ -675,6 +743,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "${prom}" + }, "gridPos": { "h": 7, "w": 8, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v0alpha1.json index e169d2bfa64..ae598c96c0e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -71,6 +79,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, @@ -93,6 +105,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 4, @@ -115,6 +131,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -137,6 +157,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, @@ -159,6 +183,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 24, @@ -181,6 +209,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 24, @@ -203,6 +235,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, @@ -225,6 +261,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v1beta1.json index b5a64a7634f..6b5a09f65ab 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v17.minspan_to_maxperrow.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -71,6 +79,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, @@ -93,6 +105,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 4, @@ -115,6 +131,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 8, @@ -137,6 +157,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, @@ -159,6 +183,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 6, "w": 24, @@ -181,6 +209,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 24, @@ -203,6 +235,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, @@ -225,6 +261,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 4, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v0alpha1.json index cc57f1b1914..a34b41d8bb6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +75,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -98,6 +106,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -126,6 +138,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -160,6 +176,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v1beta1.json index 1fcfe058203..269085d6048 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v18.gauge_options.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +75,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -98,6 +106,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -126,6 +138,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -160,6 +176,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v0alpha1.json index 44bdfd7c1a0..d71f8e881d2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -55,6 +59,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -83,6 +91,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -111,6 +123,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -140,6 +156,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -168,6 +188,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v1beta1.json index 432355ba671..288d4f1c8aa 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v19.panel_links.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -55,6 +59,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -83,6 +91,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -111,6 +123,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -140,6 +156,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -168,6 +188,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v0alpha1.json index ec7aab7bc7a..ea66d446c51 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -50,6 +54,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -73,6 +81,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -95,6 +107,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v1beta1.json index 5aaa48878d6..bd99678a8ff 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v2.panels-and-services.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -50,6 +54,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -73,6 +81,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -95,6 +107,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v0alpha1.json index 40a06e400a4..7e234377108 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -62,6 +66,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -102,6 +110,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 24, @@ -144,6 +156,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -186,6 +202,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v1beta1.json index a914c1f29b6..4f519fb3d9c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v20.variable_syntax_links.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -62,6 +66,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -102,6 +110,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 24, @@ -144,6 +156,10 @@ "type": "gauge" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -186,6 +202,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v0alpha1.json index 25823b0fd99..c4240b5dd20 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -60,6 +64,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -97,6 +105,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -136,6 +148,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -165,6 +181,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v1beta1.json index 6f5594d57f0..90783f28c4d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v21.data_links_series_to_field.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -60,6 +64,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -97,6 +105,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -136,6 +148,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -165,6 +181,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v0alpha1.json index ab9f271d900..a6e6e123cdb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v1beta1.json index b17a18593b8..19143fd0ac0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v22.table_panel_align.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v0alpha1.json index 6bf600c5014..f55f52af9cf 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v1beta1.json index 4f174d6742a..dd7c60c0e90 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v23.multi_variable_alignment.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v0alpha1.json index 876be802767..aeec2f8300d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests basic migration with default style pattern (/.*/) containing thresholds and colors. Should convert styles to fieldConfig.defaults with threshold steps.", "gridPos": { "h": 3, @@ -57,6 +61,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests comprehensive migration including: default style with thresholds/colors/unit/decimals/align/colorMode, column overrides with exact name and regex patterns, date formatting, hidden columns, and links with tooltips.", "gridPos": { "h": 3, @@ -80,6 +88,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of timeseries_aggregations transform to reduce transformation with column mappings (avg-\u003emean, max-\u003emax, min-\u003emin, total-\u003esum, current-\u003elastNotNull, count-\u003ecount).", "gridPos": { "h": 3, @@ -103,6 +115,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of timeseries_to_rows transform to seriesToRows transformation.", "gridPos": { "h": 3, @@ -126,6 +142,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of timeseries_to_columns transform to seriesToColumns transformation.", "gridPos": { "h": 3, @@ -149,6 +169,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of table transform to merge transformation. Also tests auto alignment conversion to empty string.", "gridPos": { "h": 3, @@ -172,6 +196,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests that existing transformations are preserved and new transformation from old format is appended to the list.", "gridPos": { "h": 3, @@ -208,6 +236,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests handling of mixed numeric and string threshold values (int, string, float) with proper type conversion.", "gridPos": { "h": 3, @@ -231,6 +263,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests all color mode mappings: cell-\u003ecolor-background, row-\u003ecolor-background, value-\u003ecolor-text.", "gridPos": { "h": 3, @@ -254,6 +290,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests all alignment options: left, center, right, and auto (should convert to empty string).", "gridPos": { "h": 3, @@ -277,6 +317,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests both field matcher types: byName for exact matches and byRegexp for regex patterns.", "gridPos": { "h": 3, @@ -300,6 +344,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests various link configurations: with and without tooltip, with and without target blank.", "gridPos": { "h": 3, @@ -323,6 +371,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests various date format patterns and aliases.", "gridPos": { "h": 3, @@ -346,6 +398,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "React table (table2) should not be migrated. Properties should remain unchanged.", "gridPos": { "h": 3, @@ -369,6 +425,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Angular table without styles property should not be migrated.", "gridPos": { "h": 3, @@ -392,6 +452,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Non-table panels should remain completely unchanged.", "gridPos": { "h": 3, @@ -415,6 +479,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Other panel types should not be affected by table migration.", "gridPos": { "h": 3, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v1beta1.json index d79faf07932..f9a126e5f34 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v24.table-angular.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests basic migration with default style pattern (/.*/) containing thresholds and colors. Should convert styles to fieldConfig.defaults with threshold steps.", "gridPos": { "h": 3, @@ -57,6 +61,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests comprehensive migration including: default style with thresholds/colors/unit/decimals/align/colorMode, column overrides with exact name and regex patterns, date formatting, hidden columns, and links with tooltips.", "gridPos": { "h": 3, @@ -80,6 +88,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of timeseries_aggregations transform to reduce transformation with column mappings (avg-\u003emean, max-\u003emax, min-\u003emin, total-\u003esum, current-\u003elastNotNull, count-\u003ecount).", "gridPos": { "h": 3, @@ -103,6 +115,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of timeseries_to_rows transform to seriesToRows transformation.", "gridPos": { "h": 3, @@ -126,6 +142,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of timeseries_to_columns transform to seriesToColumns transformation.", "gridPos": { "h": 3, @@ -149,6 +169,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests migration of table transform to merge transformation. Also tests auto alignment conversion to empty string.", "gridPos": { "h": 3, @@ -172,6 +196,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests that existing transformations are preserved and new transformation from old format is appended to the list.", "gridPos": { "h": 3, @@ -208,6 +236,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests handling of mixed numeric and string threshold values (int, string, float) with proper type conversion.", "gridPos": { "h": 3, @@ -231,6 +263,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests all color mode mappings: cell-\u003ecolor-background, row-\u003ecolor-background, value-\u003ecolor-text.", "gridPos": { "h": 3, @@ -254,6 +290,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests all alignment options: left, center, right, and auto (should convert to empty string).", "gridPos": { "h": 3, @@ -277,6 +317,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests both field matcher types: byName for exact matches and byRegexp for regex patterns.", "gridPos": { "h": 3, @@ -300,6 +344,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests various link configurations: with and without tooltip, with and without target blank.", "gridPos": { "h": 3, @@ -323,6 +371,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests various date format patterns and aliases.", "gridPos": { "h": 3, @@ -346,6 +398,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "React table (table2) should not be migrated. Properties should remain unchanged.", "gridPos": { "h": 3, @@ -369,6 +425,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Angular table without styles property should not be migrated.", "gridPos": { "h": 3, @@ -392,6 +452,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Non-table panels should remain completely unchanged.", "gridPos": { "h": 3, @@ -415,6 +479,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Other panel types should not be affected by table migration.", "gridPos": { "h": 3, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v0alpha1.json index 704035dffdf..92c8eaf2b14 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v0alpha1.json @@ -33,6 +33,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -55,6 +59,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v1beta1.json index 7daaf9fa380..2e0d3dbe0ef 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v25.no-op-migration.v1beta1.json @@ -33,6 +33,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -55,6 +59,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v0alpha1.json index 4ddc375e3d0..c36b9aaa1b9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v1beta1.json index ed958f0fc45..028ecd9792b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v26.text2_to_text.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "text" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v0alpha1.json index 99bdb079082..883875f9227 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v1beta1.json index e2a7c8d360f..2775106705e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v27.repeated_panels_and_constant_variable.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v0alpha1.json index 549d23f389c..baaa4bd3d9f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -56,6 +60,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -78,6 +86,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -107,6 +119,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v1beta1.json index 8fdfe74a0ca..da477bdc06d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_and_variable_properties.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -56,6 +60,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -78,6 +86,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -107,6 +119,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v0alpha1.json index f47146292f4..103dc503a7c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -56,6 +60,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -85,6 +93,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -107,6 +119,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -136,6 +152,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -159,6 +179,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "PD8C576611E62080A" + }, "gridPos": { "h": 8, "w": 8, @@ -182,6 +206,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "PD8C576611E62080A" + }, "fieldConfig": { "defaults": { "mappings": [ @@ -249,6 +277,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "PD8C576611E62080A" + }, "gridPos": { "h": 8, "w": 8, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v1beta1.json index 9e27ce9b373..fc357d68563 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v28.singlestat_migration.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -56,6 +60,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -85,6 +93,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -107,6 +119,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -136,6 +152,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -159,6 +179,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "PD8C576611E62080A" + }, "gridPos": { "h": 8, "w": 8, @@ -182,6 +206,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "PD8C576611E62080A" + }, "fieldConfig": { "defaults": { "mappings": [ @@ -249,6 +277,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "PD8C576611E62080A" + }, "gridPos": { "h": 8, "w": 8, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v0alpha1.json index 46a5be539cf..846bb168d12 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v1beta1.json index 797aa7aa93b..da06dcbea48 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v29.query_variables_refresh_and_options.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v0alpha1.json index 811f9a00d89..f1b00a18973 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -93,6 +105,10 @@ "type": "barchart" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v1beta1.json index 63203ed95de..4703aad237e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v3.no-op.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -93,6 +105,10 @@ "type": "barchart" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v0alpha1.json index e6ec721a7f3..a7847652883 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "mappings": [ @@ -125,6 +129,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -151,6 +159,10 @@ "type": "xychart" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -178,6 +190,10 @@ "type": "xychart2" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -204,6 +220,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "mappings": [ @@ -305,6 +325,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "unit": "bytes" @@ -337,6 +361,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "overrides": [ { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v1beta1.json index 240ee83acfe..21fb00e8845 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v30.value_mappings_and_tooltip_options.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "mappings": [ @@ -125,6 +129,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -151,6 +159,10 @@ "type": "xychart" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -178,6 +190,10 @@ "type": "xychart2" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -204,6 +220,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "mappings": [ @@ -305,6 +325,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "unit": "bytes" @@ -337,6 +361,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "overrides": [ { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v0alpha1.json index b3261291c34..00817bd05b6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -59,6 +63,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -99,6 +107,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -149,6 +161,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -171,6 +187,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -259,6 +279,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v1beta1.json index 74ddec4f78c..6f3fb009a55 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v31.labels_to_fields_merge.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -59,6 +63,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -99,6 +107,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -149,6 +161,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -171,6 +187,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -259,6 +279,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v0alpha1.json index bde81f8e5b9..3389666f1ef 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v0alpha1.json @@ -33,6 +33,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +75,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v1beta1.json index 18aee40e8eb..ecf3f1bbd52 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v32.no_op_migration.v1beta1.json @@ -33,6 +33,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +75,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v0alpha1.json index a860cf2dd06..142d01d9ffb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "loki", + "uid": "non-default-test-ds-uid" + }, "description": "Tests v33 migration behavior when panel datasource is explicitly null. Should remain null after migration (returnDefaultAsNull: true).", "gridPos": { "h": 3, @@ -51,6 +55,10 @@ "type": "stat" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests v33 migration behavior when panel datasource is already a proper object reference. Should remain unchanged.", "gridPos": { "h": 3, @@ -75,6 +83,10 @@ "type": "stat" }, { + "datasource": { + "type": "loki", + "uid": "non-default-test-ds-uid" + }, "description": "Tests v33 migration when panel datasource is a string name. Should convert to proper object with uid, type, apiVersion.", "gridPos": { "h": 3, @@ -98,6 +110,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests v33 migration when panel has datasource string but empty targets array. Panel datasource should still migrate.", "gridPos": { "h": 3, @@ -283,6 +299,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Nested panel with string datasource should migrate to proper object reference, proving row panel recursion works.", "gridPos": { "h": 3, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v1beta1.json index 36b1c55fb41..d9af9bca3d7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v33.panel_ds_name_to_ref.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "loki", + "uid": "non-default-test-ds-uid" + }, "description": "Tests v33 migration behavior when panel datasource is explicitly null. Should remain null after migration (returnDefaultAsNull: true).", "gridPos": { "h": 3, @@ -51,6 +55,10 @@ "type": "stat" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests v33 migration behavior when panel datasource is already a proper object reference. Should remain unchanged.", "gridPos": { "h": 3, @@ -75,6 +83,10 @@ "type": "stat" }, { + "datasource": { + "type": "loki", + "uid": "non-default-test-ds-uid" + }, "description": "Tests v33 migration when panel datasource is a string name. Should convert to proper object with uid, type, apiVersion.", "gridPos": { "h": 3, @@ -98,6 +110,10 @@ "type": "table" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests v33 migration when panel has datasource string but empty targets array. Panel datasource should still migrate.", "gridPos": { "h": 3, @@ -283,6 +299,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Nested panel with string datasource should migrate to proper object reference, proving row panel recursion works.", "gridPos": { "h": 3, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v0alpha1.json index af5a9eb4fb2..7755aa29cf7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v0alpha1.json @@ -289,6 +289,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -355,6 +359,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -386,6 +394,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -492,6 +504,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -522,6 +538,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -626,6 +646,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -689,6 +713,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -738,6 +766,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -769,6 +801,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -818,6 +854,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -849,6 +889,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -927,6 +971,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -1006,6 +1054,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v1beta1.json index 8a6009228aa..1568231f000 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v34.multiple_stats_cloudwatch.v1beta1.json @@ -289,6 +289,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -355,6 +359,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -386,6 +394,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -492,6 +504,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -522,6 +538,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -626,6 +646,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -689,6 +713,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -738,6 +766,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -769,6 +801,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -818,6 +854,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -849,6 +889,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -927,6 +971,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -1006,6 +1054,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "prometheus" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v0alpha1.json index 83e0d94fd78..9aef1000c89 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -70,6 +74,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -125,6 +133,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -154,6 +166,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -183,6 +199,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -205,6 +225,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -227,6 +251,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "unit": "bytes" @@ -254,6 +282,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v1beta1.json index 59a03171c59..5b383957bd3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v35.ensure_x_axis_visibility.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -70,6 +74,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -125,6 +133,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -154,6 +166,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { @@ -183,6 +199,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -205,6 +225,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -227,6 +251,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "unit": "bytes" @@ -254,6 +282,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "fieldConfig": { "defaults": { "custom": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v0alpha1.json index 6cfba3afdaf..4678a84253d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v0alpha1.json @@ -77,6 +77,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests null panel datasource migration with targets - should fallback to default", "gridPos": { "h": 3, @@ -100,6 +104,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests null panel datasource with empty targets array - should create default target", "gridPos": { "h": 3, @@ -123,6 +131,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests null panel datasource with missing targets - should create default target array", "gridPos": { "h": 3, @@ -180,6 +192,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel with already migrated datasource object - should preserve existing refs", "gridPos": { "h": 3, @@ -203,6 +219,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "unknown-target-datasource" + }, "description": "Tests panel with unknown datasource - should preserve as UID-only reference", "gridPos": { "h": 3, @@ -260,6 +280,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel inheriting datasource from target when panel datasource was default", "gridPos": { "h": 3, @@ -283,6 +307,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel with datasource referenced by name - should migrate to full object", "gridPos": { "h": 3, @@ -306,6 +334,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel with datasource referenced by UID - should migrate to full object", "gridPos": { "h": 3, @@ -345,6 +377,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Nested panel in collapsed row with default datasource", "gridPos": { "h": 3, @@ -368,6 +404,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Nested panel in collapsed row with unknown datasource", "gridPos": { "h": 3, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v1beta1.json index 535ea1447f0..a1b5270382b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v36.ds_name_to_ref.v1beta1.json @@ -77,6 +77,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests null panel datasource migration with targets - should fallback to default", "gridPos": { "h": 3, @@ -100,6 +104,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests null panel datasource with empty targets array - should create default target", "gridPos": { "h": 3, @@ -123,6 +131,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "description": "Tests null panel datasource with missing targets - should create default target array", "gridPos": { "h": 3, @@ -180,6 +192,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel with already migrated datasource object - should preserve existing refs", "gridPos": { "h": 3, @@ -203,6 +219,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "unknown-target-datasource" + }, "description": "Tests panel with unknown datasource - should preserve as UID-only reference", "gridPos": { "h": 3, @@ -260,6 +280,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel inheriting datasource from target when panel datasource was default", "gridPos": { "h": 3, @@ -283,6 +307,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel with datasource referenced by name - should migrate to full object", "gridPos": { "h": 3, @@ -306,6 +334,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Tests panel with datasource referenced by UID - should migrate to full object", "gridPos": { "h": 3, @@ -345,6 +377,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Nested panel in collapsed row with default datasource", "gridPos": { "h": 3, @@ -368,6 +404,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch", + "uid": "existing-target-uid" + }, "description": "Nested panel in collapsed row with unknown datasource", "gridPos": { "h": 3, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v0alpha1.json index 5daafe44636..5be318447ec 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v1beta1.json index e5b057639fb..8e1436e850a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v4.no-op.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v0alpha1.json index 4872dd21894..07538e41a8f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v1beta1.json index aeb12a936e1..88148baa546 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v5.no-op.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v0alpha1.json index 7f61b3e7b90..5cdc2d5e424 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v0alpha1.json @@ -49,6 +49,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -72,6 +76,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v1beta1.json index cb826c382bd..558e765f719 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v6.pulldowns_and_templating.v1beta1.json @@ -49,6 +49,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, @@ -72,6 +76,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 8, "w": 12, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v0alpha1.json index 100c239dc08..db8c34264b4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v1beta1.json index 2a2541d7861..18283a762cb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v7.timepicker.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v0alpha1.json index 3f575f7f5fc..8ffe55cd0d9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v0alpha1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v1beta1.json index fd2231c5509..d2ea95d4a03 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dashboards_from_v0_to_v2/v2beta1.v9.no-op.v1beta1.json @@ -27,6 +27,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -49,6 +53,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, @@ -71,6 +79,10 @@ "type": "stat" }, { + "datasource": { + "type": "prometheus", + "uid": "default-ds-uid" + }, "gridPos": { "h": 3, "w": 6, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2alpha1.json index 59ed9c457a1..c7f21881b4c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2alpha1.json @@ -558,5 +558,10 @@ "title": "Annotation filtering", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2beta1.json index 26e6d792f59..b7a613fc48b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.annotation-filtering.v42.v2beta1.json @@ -570,5 +570,10 @@ "title": "Annotation filtering", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2alpha1.json index 5449d222a2c..b6addcc81ed 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2alpha1.json @@ -1368,5 +1368,10 @@ "title": "Multi-lane annotations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2beta1.json index e23c11c69ef..f806e27a98f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/annotations/v0alpha1.multi-lane-annotations.v42.v2beta1.json @@ -1393,5 +1393,10 @@ "title": "Multi-lane annotations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2alpha1.json index 253b6471087..5fb32832089 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2alpha1.json @@ -7244,5 +7244,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2beta1.json index 54edeecb540..3ab6bb18228 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_complex.v42.v2beta1.json @@ -7345,5 +7345,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2alpha1.json index 5b384c10afc..f2cd5feadf1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2alpha1.json @@ -13081,5 +13081,10 @@ "title": "Datasource tests - Elasticsearch migration", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2beta1.json index 898dc2b2489..5ba04ac7b23 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_migration.v42.v2beta1.json @@ -13289,5 +13289,10 @@ "title": "Datasource tests - Elasticsearch migration", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2alpha1.json index 9eab3b48079..7cf034e5479 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2alpha1.json @@ -1450,5 +1450,10 @@ "title": "Datasource tests - Elasticsearch simple", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2beta1.json index 35e24952e8a..e358643fc42 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-elasticsearch/v0alpha1.elasticsearch_simple.v42.v2beta1.json @@ -1472,5 +1472,10 @@ "title": "Datasource tests - Elasticsearch simple", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2alpha1.json index 462481754b0..d30cf519eb9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2alpha1.json @@ -164,6 +164,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -239,5 +298,10 @@ "title": "Datasource tests - InfluxDB Logs", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2beta1.json index 7cfd839bf00..def63fe73f1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-logs.v42.v2beta1.json @@ -170,6 +170,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -245,5 +304,10 @@ "title": "Datasource tests - InfluxDB Logs", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2alpha1.json index 3b776907f83..7bd7146240e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2alpha1.json @@ -113,7 +113,78 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "annotate": { + "enable": false + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 2, + "grid": {}, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "resolution": 100, + "scale": 1, + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "query_as_alias": true, + "shared": false, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + }, + "zerofill": true + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -317,5 +388,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2beta1.json index a6ebf10b8f0..943bd4c0a7b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-influxdb/v0alpha1.influxdb-templated.v42.v2beta1.json @@ -117,7 +117,78 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "annotate": { + "enable": false + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 2, + "grid": {}, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "resolution": 100, + "scale": 1, + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "query_as_alias": true, + "shared": false, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + }, + "zerofill": true + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -327,5 +398,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2alpha1.json index d8a362c5029..f6e20264866 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2alpha1.json @@ -615,5 +615,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2beta1.json index 029c2bcf218..01d2f669fe1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_fakedata.v42.v2beta1.json @@ -627,5 +627,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2alpha1.json index e5078c03a19..c3feede3aca 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2alpha1.json @@ -1552,5 +1552,10 @@ "title": "Datasource tests - Loki query splitting", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2beta1.json index c2651fc75a2..6ac4f48fde4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-loki/v0alpha1.loki_query_splitting.v42.v2beta1.json @@ -1577,5 +1577,10 @@ "title": "Datasource tests - Loki query splitting", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2alpha1.json index 3faa6bf6d7b..0f908ced2aa 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2alpha1.json @@ -129,6 +129,74 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "total avg": "#6ed0e0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total avg", + "fill": 0, + "pointradius": 3, + "points": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -178,7 +246,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -227,6 +333,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -296,6 +461,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -546,5 +770,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2beta1.json index b9acf971b1d..a346f009588 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_fakedata.v42.v2beta1.json @@ -138,6 +138,74 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "total avg": "#6ed0e0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total avg", + "fill": 0, + "pointradius": 3, + "points": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -189,7 +257,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -240,6 +346,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -312,6 +477,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -566,5 +790,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2alpha1.json index 915a7a7f790..747942f6dc3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2alpha1.json @@ -147,7 +147,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -195,7 +253,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -243,7 +358,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -291,7 +463,69 @@ "kind": "bargauge", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -339,7 +573,69 @@ "kind": "bargauge", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -387,7 +683,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -435,7 +788,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -483,7 +898,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -531,7 +1006,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -579,7 +1116,38 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "string", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -627,7 +1195,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -675,7 +1303,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -723,7 +1414,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 100, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -771,7 +1525,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -819,7 +1636,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -867,7 +1747,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 50, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -915,7 +1858,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -963,7 +1969,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1011,7 +2079,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1059,7 +2187,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1107,7 +2297,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1156,7 +2408,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1205,7 +2495,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1254,7 +2582,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1303,7 +2669,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1351,7 +2755,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1399,7 +2861,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1447,7 +2966,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1514,7 +3095,79 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1562,7 +3215,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1629,7 +3344,79 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1677,7 +3464,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1725,7 +3570,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -2280,5 +4183,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2beta1.json index f28e28bdded..fa5c52ae871 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mssql/v0alpha1.mssql_unittest.v42.v2beta1.json @@ -159,7 +159,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -209,7 +267,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -259,7 +374,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -309,7 +481,69 @@ "group": "bargauge", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -359,7 +593,69 @@ "group": "bargauge", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -409,7 +705,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -459,7 +812,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -509,7 +924,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -559,7 +1034,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -609,7 +1146,38 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "string", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -659,7 +1227,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -709,7 +1337,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -759,7 +1450,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 100, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -809,7 +1563,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -859,7 +1676,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -909,7 +1789,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 50, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -959,7 +1902,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1009,7 +2015,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1059,7 +2127,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1109,7 +2237,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1159,7 +2349,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1210,7 +2462,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1261,7 +2551,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1312,7 +2640,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1363,7 +2729,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1413,7 +2817,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1463,7 +2925,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1513,7 +3032,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1583,7 +3164,79 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1633,7 +3286,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1703,7 +3418,79 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1753,7 +3540,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1803,7 +3648,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -2360,5 +4263,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2alpha1.json index bd3a41d6f40..59f1c712177 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2alpha1.json @@ -128,6 +128,74 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "total avg": "#6ed0e0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total avg", + "fill": 0, + "pointradius": 3, + "points": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -179,6 +247,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -249,6 +376,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -299,7 +485,46 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "link": false, + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -548,5 +773,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2beta1.json index fbb9f11c316..3f782078e85 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_fakedata.v42.v2beta1.json @@ -137,6 +137,74 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "total avg": "#6ed0e0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total avg", + "fill": 0, + "pointradius": 3, + "points": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -190,6 +258,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -263,6 +390,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -315,7 +501,46 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "link": false, + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -568,5 +793,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2alpha1.json index 007f6f3f04c..ccfd35d981e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2alpha1.json @@ -147,7 +147,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -195,7 +253,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -243,7 +358,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -291,7 +463,69 @@ "kind": "bargauge", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -339,7 +573,69 @@ "kind": "bargauge", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -387,7 +683,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -435,7 +788,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -483,7 +898,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -531,7 +1006,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -579,7 +1116,38 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "string", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -627,7 +1195,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -675,7 +1303,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -723,7 +1414,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 100, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -771,7 +1525,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -819,7 +1636,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -867,7 +1747,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 50, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -915,7 +1858,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -963,7 +1969,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1011,7 +2079,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1060,7 +2188,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time_sec", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1109,7 +2275,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time_sec", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1158,7 +2362,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time_sec", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1207,7 +2449,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1255,7 +2535,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1303,7 +2641,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1351,7 +2746,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1399,7 +2856,79 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1447,7 +2976,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1495,7 +3086,79 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1543,7 +3206,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1591,7 +3312,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -2123,5 +3902,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2beta1.json index 35767416230..643298fb85c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-mysql/v0alpha1.mysql_unittest.v42.v2beta1.json @@ -159,7 +159,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -209,7 +267,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -259,7 +374,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -309,7 +481,69 @@ "group": "bargauge", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -359,7 +593,69 @@ "group": "bargauge", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -409,7 +705,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -459,7 +812,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -509,7 +924,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -559,7 +1034,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -609,7 +1146,38 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "string", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -659,7 +1227,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -709,7 +1337,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -759,7 +1450,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 100, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -809,7 +1563,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -859,7 +1676,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -909,7 +1789,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 50, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -959,7 +1902,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1009,7 +2015,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1059,7 +2127,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1110,7 +2238,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time_sec", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1161,7 +2327,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time_sec", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1212,7 +2416,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time_sec", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1263,7 +2505,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1313,7 +2593,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1363,7 +2701,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1413,7 +2808,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1463,7 +2920,79 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1513,7 +3042,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1563,7 +3154,79 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "MovingAverageValueOne", + "dashes": true, + "lines": false + }, + { + "alias": "MovingAverageValueTwo", + "dashes": true, + "lines": false, + "yaxis": 1 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1613,7 +3276,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1663,7 +3384,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -2197,5 +3976,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2alpha1.json index 71e90cc1bac..893d135c144 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2alpha1.json @@ -68,6 +68,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -119,6 +178,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -194,5 +312,10 @@ "title": "Datasource tests - OpenTSDB", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2beta1.json index 9566977e001..5086e9f987d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb.v42.v2beta1.json @@ -72,6 +72,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -125,6 +184,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -200,5 +318,10 @@ "title": "Datasource tests - OpenTSDB", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2alpha1.json index ccd7b7cac51..deb7d353db8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2alpha1.json @@ -84,6 +84,65 @@ "spec": { "pluginVersion": "8.1.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -148,6 +207,65 @@ "spec": { "pluginVersion": "8.1.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -219,5 +337,10 @@ "title": "Datasource tests - OpenTSDB v2.3", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2beta1.json index dd46ba3407a..342f5a0a94c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-opentsdb/v0alpha1.opentsdb_v23.v42.v2beta1.json @@ -88,6 +88,65 @@ "version": "8.1.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -154,6 +213,65 @@ "version": "8.1.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -225,5 +343,10 @@ "title": "Datasource tests - OpenTSDB v2.3", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2alpha1.json index dd5972aef39..0e222d96742 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2alpha1.json @@ -170,6 +170,74 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "total avg": "#6ed0e0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total avg", + "fill": 0, + "pointradius": 3, + "points": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -221,6 +289,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -291,6 +418,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -341,7 +527,46 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "link": false, + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -590,5 +815,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2beta1.json index 707c89428e3..9ece61d256d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_fakedata.v42.v2beta1.json @@ -179,6 +179,74 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "total avg": "#6ed0e0" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "total avg", + "fill": 0, + "pointradius": 3, + "points": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -232,6 +300,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -305,6 +432,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -357,7 +543,46 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "link": false, + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -610,5 +835,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2alpha1.json index 1b70b5d07eb..a7bec316030 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2alpha1.json @@ -147,7 +147,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -195,7 +253,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -243,7 +358,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -291,7 +463,69 @@ "kind": "bargauge", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -339,7 +573,69 @@ "kind": "bargauge", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -387,7 +683,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -435,7 +788,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -483,7 +898,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -531,7 +1006,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -579,7 +1116,38 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 1, + "desc": false + }, + "styles": [ + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "string", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -627,7 +1195,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -675,7 +1303,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -723,7 +1414,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 100, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -771,7 +1525,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -819,7 +1636,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -867,7 +1747,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 50, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -915,7 +1858,70 @@ "kind": "histogram", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -963,7 +1969,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1011,7 +2079,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1060,7 +2188,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1109,7 +2275,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1158,7 +2362,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1207,7 +2449,45 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1255,7 +2535,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1303,7 +2641,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1351,7 +2746,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1399,7 +2856,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1447,7 +2964,69 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1495,7 +3074,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1543,7 +3182,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1591,7 +3288,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -2121,5 +3876,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2beta1.json index 7878e91dac5..ce0dd08d44d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-postgres/v0alpha1.postgres_unittest.v42.v2beta1.json @@ -159,7 +159,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -209,7 +267,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -259,7 +374,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -309,7 +481,69 @@ "group": "bargauge", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -359,7 +593,69 @@ "group": "bargauge", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -409,7 +705,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -459,7 +812,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -509,7 +924,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -559,7 +1034,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -609,7 +1146,38 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 1, + "desc": false + }, + "styles": [ + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "string", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -659,7 +1227,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": true, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -709,7 +1337,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -759,7 +1450,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 100, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -809,7 +1563,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -859,7 +1676,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -909,7 +1789,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 50, + "mode": "histogram", + "show": true, + "values": [ + "current" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -959,7 +1902,70 @@ "group": "histogram", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": false, + "total": true, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "buckets": 20, + "mode": "histogram", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1009,7 +2015,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1059,7 +2127,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1110,7 +2238,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1161,7 +2327,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1212,7 +2416,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1263,7 +2505,45 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1313,7 +2593,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1363,7 +2701,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1413,7 +2808,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1463,7 +2920,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1513,7 +3030,69 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1563,7 +3142,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1613,7 +3252,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1663,7 +3360,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 3, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": true, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -2195,5 +3950,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2alpha1.json index 58f0b2cf4df..d7dded5b99f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2alpha1.json @@ -1371,5 +1371,10 @@ "title": "Bar Gauge Demo Unfilled", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2beta1.json index b1046fe5ca3..f1d552852e8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.bar-gauge-demo2.v42.v2beta1.json @@ -1434,5 +1434,10 @@ "title": "Bar Gauge Demo Unfilled", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2alpha1.json index 9f0da1593eb..d31a3f25ea2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2alpha1.json @@ -1698,5 +1698,10 @@ "title": "TestData - Demo Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2beta1.json index 3e11006d1de..74943a89cf9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.demo1.v42.v2beta1.json @@ -1745,5 +1745,10 @@ "title": "TestData - Demo Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2alpha1.json index ca657342364..e557b4f80a6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2alpha1.json @@ -2880,5 +2880,10 @@ "title": "New Features in v7.4", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2beta1.json index 0c8b7143a91..0ad4e83973b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v74.v42.v2beta1.json @@ -2955,5 +2955,10 @@ "title": "New Features in v7.4", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2alpha1.json index dcfd34332f4..ad6e731fd8d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2alpha1.json @@ -3951,5 +3951,10 @@ "title": "New Features in v8.0", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2beta1.json index 93b501b2222..4f087f02750 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/datasource-testdata/v0alpha1.new_features_in_v8.v42.v2beta1.json @@ -4072,5 +4072,10 @@ "title": "New Features in v8.0", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2alpha1.json index 28ea4680f2e..160c0cdf458 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2alpha1.json @@ -673,5 +673,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2beta1.json index af64f4a2f02..8d1436def13 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-Kitchen-Sink.v42.v2beta1.json @@ -687,5 +687,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2alpha1.json index 5f7f66dd3cc..1629c425da7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2alpha1.json @@ -261,5 +261,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2beta1.json index a4681683ba5..fd375b98fed 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-horizontally.v42.v2beta1.json @@ -263,5 +263,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2alpha1.json index f8f9922016b..dde9ab81f9c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2alpha1.json @@ -269,5 +269,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2beta1.json index 96c5247c4f4..04266fae41b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-panel-vertically.v42.v2beta1.json @@ -274,5 +274,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2alpha1.json index e7e365773f1..f1ef5ec1c11 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2alpha1.json @@ -326,5 +326,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2beta1.json index 8cb12e2e45f..8344ab2fd3e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-horizontal-panel.v42.v2beta1.json @@ -331,5 +331,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2alpha1.json index 62c2ef1f9bc..b3c25fda752 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2alpha1.json @@ -326,5 +326,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2beta1.json index 4e7764ff205..facb775e9f1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-a-row-with-a-repeating-vertical-panel.v42.v2beta1.json @@ -331,5 +331,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2alpha1.json index cc3254f517b..f4a9ccc966a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2alpha1.json @@ -210,5 +210,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2beta1.json index df7016f1969..79c21a744ec 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/e2e-repeats/v0alpha1.Repeating-an-empty-row.v42.v2beta1.json @@ -212,5 +212,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2alpha1.json index 3d8e275556b..d3e309f9d05 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2alpha1.json @@ -469,5 +469,10 @@ "title": "Link Extensions (onClick)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2beta1.json index a783ef609f2..2d1d0f2e529 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-onclick-extensions.v42.v2beta1.json @@ -482,5 +482,10 @@ "title": "Link Extensions (onClick)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2alpha1.json index 98e0b3fd047..fc48dd77960 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2alpha1.json @@ -327,5 +327,10 @@ "title": "Link Extensions (path)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2beta1.json index 5376f4e3832..8c998ee4b2c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/extensions/v0alpha1.link-path-extensions.v42.v2beta1.json @@ -333,5 +333,10 @@ "title": "Link Extensions (path)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2alpha1.json index 2f913de363f..1ed897f3cc8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2alpha1.json @@ -1167,5 +1167,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2beta1.json index 614ac4cabec..40cc11e8cb9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.datadata-macros.v42.v2beta1.json @@ -1201,5 +1201,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2alpha1.json index 6b40487f1d0..2b16e9ce76b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2alpha1.json @@ -168,5 +168,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2beta1.json index 0bd988b9902..59e7b0a96bc 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.global-variables-and-interpolation.v42.v2beta1.json @@ -172,5 +172,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2alpha1.json index abab61bd552..7480afb75db 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2alpha1.json @@ -205,5 +205,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2beta1.json index 4fc9cedb62a..cd93214ebc3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-dashboard-links-and-variables.v42.v2beta1.json @@ -209,5 +209,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2alpha1.json index 2d423c83c3d..f8f7fbc5350 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2alpha1.json @@ -565,5 +565,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2beta1.json index 2be4b39a06f..897abd7a0c7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-panels.v42.v2beta1.json @@ -574,5 +574,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2alpha1.json index 17ee9515ded..85cb38c13ff 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2alpha1.json @@ -485,5 +485,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2beta1.json index fbe90caa7bd..a1ec03cd26a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-repeating-rows.v42.v2beta1.json @@ -491,5 +491,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2alpha1.json index 05b4c6ed70c..123f410cac0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2alpha1.json @@ -136,5 +136,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2beta1.json index c9ba98c312b..0f3f2ab00a2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.templating-textbox-e2e-scenarios.v42.v2beta1.json @@ -140,5 +140,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2alpha1.json index 16148c1ab23..4a9e24d85f6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2alpha1.json @@ -86,6 +86,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [ { "targetBlank": false, @@ -303,7 +361,15 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "## Data link variables overview\n\nThis dashboard presents variables that one can use when creating *data links*. All links redirect to this dashboard and this panel represents the values that were interpolated in the link that was clicked.\n\n\n#### Series variables\n1. **Name:** \u003cspan style=\"color: orange;\"\u003e$seriesName\u003c/span\u003e\n2. **label.datacenter:** \u003cspan style=\"color: orange;\"\u003e$labelDatacenter\u003c/span\u003e\n3. **label.datacenter.region:** \u003cspan style=\"color: orange;\"\u003e$labelDatacenterRegion\u003c/span\u003e\n\n#### Field variables\n1. **Name:** \u003cspan style=\"color: orange;\"\u003e$fieldName\u003c/span\u003e\n\n#### Value variables\n1. **Time:** \u003cspan style=\"color: orange;\"\u003e$valueTime\u003c/span\u003e\n2. **Numeric:** \u003cspan style=\"color: orange;\"\u003e$valueNumeric\u003c/span\u003e\n3. **Text:** \u003cspan style=\"color: orange;\"\u003e$valueText\u003c/span\u003e\n4. **Calc:** \u003cspan style=\"color: orange;\"\u003e$valueCalc\u003c/span\u003e\n\n", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -354,6 +420,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [ { "targetBlank": false, @@ -579,5 +703,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2beta1.json index 1f8d4d5eee6..62b30aa6480 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-datalinks.v42.v2beta1.json @@ -91,6 +91,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [ { "targetBlank": false, @@ -314,7 +372,15 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "## Data link variables overview\n\nThis dashboard presents variables that one can use when creating *data links*. All links redirect to this dashboard and this panel represents the values that were interpolated in the link that was clicked.\n\n\n#### Series variables\n1. **Name:** \u003cspan style=\"color: orange;\"\u003e$seriesName\u003c/span\u003e\n2. **label.datacenter:** \u003cspan style=\"color: orange;\"\u003e$labelDatacenter\u003c/span\u003e\n3. **label.datacenter.region:** \u003cspan style=\"color: orange;\"\u003e$labelDatacenterRegion\u003c/span\u003e\n\n#### Field variables\n1. **Name:** \u003cspan style=\"color: orange;\"\u003e$fieldName\u003c/span\u003e\n\n#### Value variables\n1. **Time:** \u003cspan style=\"color: orange;\"\u003e$valueTime\u003c/span\u003e\n2. **Numeric:** \u003cspan style=\"color: orange;\"\u003e$valueNumeric\u003c/span\u003e\n3. **Text:** \u003cspan style=\"color: orange;\"\u003e$valueText\u003c/span\u003e\n4. **Calc:** \u003cspan style=\"color: orange;\"\u003e$valueCalc\u003c/span\u003e\n\n", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -367,6 +433,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [ { "targetBlank": false, @@ -592,5 +716,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2alpha1.json index 171b505001e..f754cbd766a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2alpha1.json @@ -62,6 +62,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -109,7 +167,15 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "## Data center = $datacenter\n\n### server = $server\n\n#### pod = $pod", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -163,7 +229,68 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -334,5 +461,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2beta1.json index 4b2a7a98790..8a8cffdf465 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables-drilldown.v42.v2beta1.json @@ -67,6 +67,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -116,7 +174,15 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "## Data center = $datacenter\n\n### server = $server\n\n#### pod = $pod", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -172,7 +238,68 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -349,5 +476,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2alpha1.json index 837c5cbfa5a..b1dbd3de041 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2alpha1.json @@ -120,7 +120,7 @@ "value": [ { "title": "filter", - "url": "http://localhost:3000/d/-Y-tnEDWk/templating-nested-template-variables?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}" + "url": "http://localhost:3000/d/-Y-tnEDWk/templating-nested-template-variables?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}" } ] } @@ -167,6 +167,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -214,7 +273,15 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "## Data center = $datacenter\n\n### server = $server\n\n#### pod = $pod", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -264,7 +331,59 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -639,5 +758,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2beta1.json index 2b61b379a04..9089dd1d1fb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-nested-variables.v42.v2beta1.json @@ -124,7 +124,7 @@ "value": [ { "title": "filter", - "url": "http://localhost:3000/d/-Y-tnEDWk/templating-nested-template-variables?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}" + "url": "http://localhost:3000/d/-Y-tnEDWk/templating-nested-template-variables?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}" } ] } @@ -174,6 +174,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -223,7 +282,15 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "## Data center = $datacenter\n\n### server = $server\n\n#### pod = $pod", + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -276,7 +343,59 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -661,5 +780,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2alpha1.json index efa298e1ec2..9eaf955bb68 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2alpha1.json @@ -247,5 +247,10 @@ "title": "Test variable output", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2beta1.json index 17fa40a073b..395867814e0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-test-variable-output.v42.v2beta1.json @@ -255,5 +255,10 @@ "title": "Test variable output", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2alpha1.json index 8ae6fb9f2cd..81d61c2509b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2alpha1.json @@ -171,6 +171,65 @@ "spec": { "pluginVersion": "7.2.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -259,5 +318,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2beta1.json index b07bdc72f60..01936dded6b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-textbox.v42.v2beta1.json @@ -177,6 +177,65 @@ "version": "7.2.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -265,5 +324,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2alpha1.json index 08f14e2614f..7eb15579259 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2alpha1.json @@ -84,6 +84,67 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -198,5 +259,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2beta1.json index a1ff094b67b..c89000daee7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/feature-templating/v0alpha1.testdata-variables-that-update-on-time-change.v42.v2beta1.json @@ -89,6 +89,67 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": true, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -207,5 +268,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2alpha1.json index f71a17e660d..83c4dd25a5c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2alpha1.json @@ -536,5 +536,10 @@ "title": "Live flakey stream (w/ liveNow)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2beta1.json index 892812351b8..89bea6fc4d4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey-refresh.v42.v2beta1.json @@ -545,5 +545,10 @@ "title": "Live flakey stream (w/ liveNow)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2alpha1.json index abf4e4cdcef..017171df8ef 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2alpha1.json @@ -536,5 +536,10 @@ "title": "Live flakey stream", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2beta1.json index 68c0083c4ab..32cec1120c6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-flakey.v42.v2beta1.json @@ -545,5 +545,10 @@ "title": "Live flakey stream", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2alpha1.json index f3777d0eedd..ca4649e18a8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2alpha1.json @@ -707,5 +707,10 @@ "title": "Live publish test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2beta1.json index 66e94e73744..e87b98713e2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-publish.v42.v2beta1.json @@ -720,5 +720,10 @@ "title": "Live publish test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2alpha1.json index efe66b835b3..ebe0f2098d8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2alpha1.json @@ -1034,5 +1034,10 @@ "title": "Live streaming examples", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2beta1.json index 5ad3b53ea98..051a06f0f94 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/live/v0alpha1.live-streams.v42.v2beta1.json @@ -1054,5 +1054,10 @@ "title": "Live streaming examples", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v1beta1.json index 5ae52076acc..7542cf17652 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v1beta1.json @@ -296,6 +296,7 @@ } }, { + "content": "# Graph panel \u003e\u003e Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions", "datasource": { "type": "grafana-testdata-datasource" }, @@ -306,15 +307,7 @@ "y": 0 }, "id": 6, - "options": { - "code": { - "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" - }, + "mode": "markdown", "pluginVersion": "11.0.0-pre", "targets": [ { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2alpha1.json index f8826a3a699..21d45e91f10 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2alpha1.json @@ -123,6 +123,42 @@ "spec": { "pluginVersion": "9.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "right", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + }, "cellHeight": "sm", "footer": { "countRows": false, @@ -270,6 +306,10 @@ "spec": { "pluginVersion": "9.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-piechart-panel", + "originalOptions": {} + }, "legend": { "displayMode": "list", "placement": "bottom", @@ -402,6 +442,41 @@ "spec": { "pluginVersion": "10.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-worldmap-panel", + "originalOptions": { + "circleMaxSize": 30, + "circleMinSize": 2, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 0, + "esMetric": "Count", + "hideEmpty": false, + "hideZero": false, + "initialZoom": 1, + "locationData": "countries", + "mapCenter": "(0°, 0°)", + "mapCenterLatitude": 0, + "mapCenterLongitude": 0, + "mouseWheelZoom": false, + "showLegend": true, + "stickyLabels": false, + "tableQueryOptions": { + "geohashField": "geohash", + "latitudeField": "latitude", + "longitudeField": "longitude", + "metricField": "metric", + "queryType": "geohash" + }, + "thresholds": "0,10", + "unitPlural": "", + "unitSingle": "", + "valueName": "total" + } + }, "basemap": { "name": "Basemap", "type": "default" @@ -562,6 +637,69 @@ "spec": { "pluginVersion": "11.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -667,6 +805,67 @@ "spec": { "pluginVersion": "11.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "histogram", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:193", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:194", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -775,6 +974,70 @@ "spec": { "pluginVersion": "11.3.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -880,6 +1143,65 @@ "spec": { "pluginVersion": "11.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -934,13 +1256,13 @@ "spec": { "pluginVersion": "11.0.0-pre", "options": { - "code": { - "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" + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "# Graph panel \u003e\u003e Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions", + "mode": "markdown" + } + } }, "fieldConfig": { "defaults": {}, @@ -1031,7 +1353,68 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-singlestat-panel", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1469,5 +1852,10 @@ "title": "Devenv - Panel migrations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2beta1.json index 8eea5775903..ed7123f5e38 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/migrations/v0alpha1.migrations.v42.v2beta1.json @@ -130,6 +130,42 @@ "version": "9.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "right", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + }, "cellHeight": "sm", "footer": { "countRows": false, @@ -283,6 +319,10 @@ "version": "9.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-piechart-panel", + "originalOptions": {} + }, "legend": { "displayMode": "list", "placement": "bottom", @@ -421,6 +461,41 @@ "version": "10.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-worldmap-panel", + "originalOptions": { + "circleMaxSize": 30, + "circleMinSize": 2, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 0, + "esMetric": "Count", + "hideEmpty": false, + "hideZero": false, + "initialZoom": 1, + "locationData": "countries", + "mapCenter": "(0°, 0°)", + "mapCenterLatitude": 0, + "mapCenterLongitude": 0, + "mouseWheelZoom": false, + "showLegend": true, + "stickyLabels": false, + "tableQueryOptions": { + "geohashField": "geohash", + "latitudeField": "latitude", + "longitudeField": "longitude", + "metricField": "metric", + "queryType": "geohash" + }, + "thresholds": "0,10", + "unitPlural": "", + "unitSingle": "", + "valueName": "total" + } + }, "basemap": { "name": "Basemap", "type": "default" @@ -587,6 +662,69 @@ "version": "11.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -698,6 +836,67 @@ "version": "11.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "histogram", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:193", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:194", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -811,6 +1010,70 @@ "version": "11.3.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -922,6 +1185,65 @@ "version": "11.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true, "legend": { "calcs": [], @@ -979,13 +1301,13 @@ "version": "11.0.0-pre", "spec": { "options": { - "code": { - "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" + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "# Graph panel \u003e\u003e Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions", + "mode": "markdown" + } + } }, "fieldConfig": { "defaults": {}, @@ -1082,7 +1404,68 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-singlestat-panel", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1520,5 +1903,10 @@ "title": "Devenv - Panel migrations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2alpha1.json index 78f2a2b6030..058a8806a5e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2alpha1.json @@ -859,5 +859,10 @@ "title": "BarChart - Panel Tests - Value sizing", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2beta1.json index c60ab8343a6..6c3fa8ae1a9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-autosizing.v42.v2beta1.json @@ -880,5 +880,10 @@ "title": "BarChart - Panel Tests - Value sizing", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2alpha1.json index 8f969cbef36..0f77a66f203 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2alpha1.json @@ -428,5 +428,10 @@ "title": "BarChart - Label Rotation \u0026 Skipping", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2beta1.json index 9290dd4ff14..3ad88c72861 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-label-rotation-skipping.v42.v2beta1.json @@ -437,5 +437,10 @@ "title": "BarChart - Label Rotation \u0026 Skipping", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2alpha1.json index 522857ab19a..8bc7997b3d4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2alpha1.json @@ -535,5 +535,10 @@ "title": "BarChart - Panel Tests - Series toggle / bar widths", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2beta1.json index 9459814d20b..7a04ed00d31 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-series-toggle.v42.v2beta1.json @@ -548,5 +548,10 @@ "title": "BarChart - Panel Tests - Series toggle / bar widths", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2alpha1.json index f25d5355ccc..e5369a162f7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2alpha1.json @@ -1682,5 +1682,10 @@ "title": "BarChart - Thresholds \u0026 Mappings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2beta1.json index 0d8c2dbf2a1..208c4c112c0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-thresholds-mappings.v42.v2beta1.json @@ -1721,5 +1721,10 @@ "title": "BarChart - Thresholds \u0026 Mappings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2alpha1.json index db478ad7e3d..bd95597bf13 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2alpha1.json @@ -1127,5 +1127,10 @@ "title": "Panel Tests - Bar Chart Tooltips \u0026 Legends", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2beta1.json index 4ea638cf0eb..3109835cd91 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-barchart/v0alpha1.barchart-tooltips-legends.v42.v2beta1.json @@ -1155,5 +1155,10 @@ "title": "Panel Tests - Bar Chart Tooltips \u0026 Legends", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2alpha1.json index 0e540c7e66e..290ee546192 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2alpha1.json @@ -1412,5 +1412,10 @@ "title": "Bar Gauge Demo", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2beta1.json index cc190aaa2e0..ebfa6d31425 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.bar_gauge_demo.v42.v2beta1.json @@ -1548,5 +1548,10 @@ "title": "Bar Gauge Demo", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2alpha1.json index c88ce3b28e1..bd408ee62ee 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2alpha1.json @@ -1922,5 +1922,10 @@ "title": "Panel Tests - Bar Gauge", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2beta1.json index 1aa4b0e1a85..cc604bc2045 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge.v42.v2beta1.json @@ -2052,5 +2052,10 @@ "title": "Panel Tests - Bar Gauge", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2alpha1.json index 4f782695385..2aa2d935923 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2alpha1.json @@ -1214,5 +1214,10 @@ "title": "Panel Tests - Bar Gauge 2", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2beta1.json index 777a64366ba..92be6f0c11c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-bargauge/v0alpha1.panel_tests_bar_gauge2.v42.v2beta1.json @@ -1262,5 +1262,10 @@ "title": "Panel Tests - Bar Gauge 2", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2alpha1.json index 97283f755fb..6d92fbd46bb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2alpha1.json @@ -640,5 +640,10 @@ "title": "Candlestick", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2beta1.json index 83ab2dd5571..0ce4c776fb5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-candlestick/v0alpha1.candlestick.v42.v2beta1.json @@ -653,5 +653,10 @@ "title": "Candlestick", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2alpha1.json index f5cb9c3c909..2976d37dc0f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2alpha1.json @@ -4064,5 +4064,10 @@ "title": "Panel Tests - Canvas Connection Examples", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2beta1.json index 49910daa683..47fb71205e2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-connection-examples.v42.v2beta1.json @@ -4074,5 +4074,10 @@ "title": "Panel Tests - Canvas Connection Examples", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2alpha1.json index e5648af2325..c9e5b0662df 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2alpha1.json @@ -3503,5 +3503,10 @@ "title": "Panel Tests - Canvas Datalinks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2beta1.json index 8f705b659b6..d63bb93d321 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-datalinks.v42.v2beta1.json @@ -3506,5 +3506,10 @@ "title": "Panel Tests - Canvas Datalinks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2alpha1.json index b32f594a99e..8d2bdc0d36c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2alpha1.json @@ -4096,5 +4096,10 @@ "title": "Panel Tests - Canvas Examples", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2beta1.json index aa7b95b6dca..0c650fd4f87 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-canvas/v0alpha1.canvas-examples.v42.v2beta1.json @@ -4113,5 +4113,10 @@ "title": "Panel Tests - Canvas Examples", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2alpha1.json index 7d0174aecaa..42c2a374b1c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2alpha1.json @@ -66,6 +66,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -115,6 +175,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -164,6 +284,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -213,6 +393,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -262,6 +502,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "µs", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -311,6 +609,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -360,6 +718,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -409,6 +825,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -458,6 +934,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -507,6 +1043,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -556,6 +1150,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -605,6 +1259,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -654,6 +1366,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -871,5 +1642,10 @@ "title": "Panel Tests - Auto Decimals", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2beta1.json index c2083797bdf..c1013a5bdcd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.auto_decimals.v42.v2beta1.json @@ -70,6 +70,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -121,6 +181,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -172,6 +292,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -223,6 +403,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -274,6 +514,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "µs", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -325,6 +623,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -376,6 +734,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -427,6 +843,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -478,6 +954,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -529,6 +1065,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -580,6 +1174,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -631,6 +1285,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -682,6 +1394,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -899,5 +1670,10 @@ "title": "Panel Tests - Auto Decimals", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2alpha1.json index 12d4efa68b6..bcb9fba2fe9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2alpha1.json @@ -471,5 +471,10 @@ "title": "Gradient Color modes", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2beta1.json index 3c1e8803dda..54a0b0d198d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.color_modes.v42.v2beta1.json @@ -481,5 +481,10 @@ "title": "Gradient Color modes", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2alpha1.json index 379d5597285..92b60103171 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2alpha1.json @@ -132,7 +132,68 @@ "kind": "stat", "spec": { "pluginVersion": "6.2.0-pre", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p99", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -176,7 +237,68 @@ "kind": "stat", "spec": { "pluginVersion": "6.2.0-pre", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p95", + "prefixFontSize": "80%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -220,7 +342,68 @@ "kind": "stat", "spec": { "pluginVersion": "6.2.0-pre", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p90", + "prefixFontSize": "80%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -302,6 +485,71 @@ "spec": { "pluginVersion": "6.2.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue", + "B-series": "dark-purple", + "C-series": "purple", + "Q-series": "dark-blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 3, + "fillGradient": 0, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -347,6 +595,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -392,6 +700,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -476,6 +844,71 @@ "spec": { "pluginVersion": "6.2.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue", + "B-series": "dark-purple", + "C-series": "purple", + "Q-series": "dark-blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 3, + "fillGradient": 0, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -521,6 +954,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -566,7 +1057,68 @@ "kind": "stat", "spec": { "pluginVersion": "6.2.0-pre", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p90", + "prefixFontSize": "80%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -610,6 +1162,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -655,6 +1267,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -700,6 +1372,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -745,6 +1477,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -790,6 +1582,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -835,6 +1687,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "purple" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -880,6 +1792,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "orange" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -964,6 +1936,71 @@ "spec": { "pluginVersion": "6.2.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue", + "B-series": "dark-purple", + "C-series": "purple", + "Q-series": "dark-blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 3, + "fillGradient": 0, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1009,6 +2046,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1054,6 +2151,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1099,6 +2256,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "purple" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1144,6 +2361,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "orange" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -2073,5 +3350,10 @@ "title": "Lazy Loading", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2beta1.json index 2767a76315e..b1b07fa0f56 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.lazy_loading.v42.v2beta1.json @@ -140,7 +140,68 @@ "group": "stat", "version": "6.2.0-pre", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p99", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -187,7 +248,68 @@ "group": "stat", "version": "6.2.0-pre", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p95", + "prefixFontSize": "80%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -234,7 +356,68 @@ "group": "stat", "version": "6.2.0-pre", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p90", + "prefixFontSize": "80%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -325,6 +508,71 @@ "version": "6.2.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue", + "B-series": "dark-purple", + "C-series": "purple", + "Q-series": "dark-blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 3, + "fillGradient": 0, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -373,6 +621,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -421,6 +729,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -514,6 +882,71 @@ "version": "6.2.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue", + "B-series": "dark-purple", + "C-series": "purple", + "Q-series": "dark-blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 3, + "fillGradient": 0, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -562,6 +995,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -610,7 +1101,68 @@ "group": "stat", "version": "6.2.0-pre", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "#73BF69", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "p90", + "prefixFontSize": "80%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -657,6 +1209,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -705,6 +1317,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -753,6 +1425,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -801,6 +1533,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -849,6 +1641,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -897,6 +1749,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "purple" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -945,6 +1857,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "orange" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1038,6 +2010,71 @@ "version": "6.2.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue", + "B-series": "dark-purple", + "C-series": "purple", + "Q-series": "dark-blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 3, + "fillGradient": 0, + "legend": { + "alignAsTable": true, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1086,6 +2123,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1134,6 +2231,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "blue" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1182,6 +2339,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "purple" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -1230,6 +2447,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "orange" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -2229,5 +3506,10 @@ "title": "Lazy Loading", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2alpha1.json index 03cea1fc2c8..ce9d8e17187 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2alpha1.json @@ -1843,5 +1843,10 @@ "title": "Panel \u0026 data links in stat, gauge and bargauge", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2beta1.json index 6fbdb415483..fe5fbfda4aa 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.linked-viz.v42.v2beta1.json @@ -1881,5 +1881,10 @@ "title": "Panel \u0026 data links in stat, gauge and bargauge", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2alpha1.json index 5723bef32ca..0572d6b73c0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2alpha1.json @@ -67,7 +67,68 @@ "kind": "stat", "spec": { "pluginVersion": "6.2.0-pre", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -258,7 +319,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -354,7 +473,68 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "#5794F2", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "100%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -515,7 +695,68 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "#5794F2", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "100%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -676,7 +917,65 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -819,7 +1118,68 @@ "kind": "stat", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "#5794F2", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "100%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1107,5 +1467,10 @@ "title": "Panel Tests - With \u0026 Without title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2beta1.json index 93173c86f2b..deca04a6634 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.panels_without_title.v42.v2beta1.json @@ -71,7 +71,68 @@ "group": "stat", "version": "6.2.0-pre", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -268,7 +329,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -368,7 +487,68 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "#5794F2", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "100%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -534,7 +714,68 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "#5794F2", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "100%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -700,7 +941,65 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -847,7 +1146,68 @@ "group": "stat", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "singlestat", + "originalOptions": { + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "#5794F2", + "#d44a3a" + ], + "format": "ms", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "100%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "120%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1137,5 +1497,10 @@ "title": "Panel Tests - With \u0026 Without title", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2alpha1.json index 15f76709e5e..0c5ddf56280 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2alpha1.json @@ -614,5 +614,10 @@ "title": "Datasource tests - Shared Queries", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2beta1.json index be9740c4b92..15ca6962fc8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-common/v0alpha1.shared_queries.v42.v2beta1.json @@ -630,5 +630,10 @@ "title": "Datasource tests - Shared Queries", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2alpha1.json index d28a40a68f1..08343d13d55 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2alpha1.json @@ -139,5 +139,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2beta1.json index aedaf24d379..aaf9456f795 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-dashlist/v0alpha1.dashlist.v42.v2beta1.json @@ -141,5 +141,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2alpha1.json index 7b820200d04..1a01292a17e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2alpha1.json @@ -138,5 +138,10 @@ "title": "Datagrid example", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2beta1.json index ec12c171f3a..fc5049c6d79 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-datagrid/v0alpha1.datagrid_metric_values.v42.v2beta1.json @@ -144,5 +144,10 @@ "title": "Datagrid example", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2alpha1.json index 2ca31f3255f..69033e3dfc5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2alpha1.json @@ -130,5 +130,10 @@ "title": "Panel Tests - Flame Graph", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2beta1.json index 10b0b3ed930..982f4088303 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-flamegraph/v0alpha1.panel_tests_flame_graph.v42.v2beta1.json @@ -134,5 +134,10 @@ "title": "Panel Tests - Flame Graph", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2alpha1.json index f9046bea886..706d0bafd47 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2alpha1.json @@ -499,5 +499,10 @@ "title": "Panel Tests - Gauge Multi Series", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2beta1.json index da3a0f5e6f1..d0cbc9aa44e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge-multi-series.v42.v2beta1.json @@ -534,5 +534,10 @@ "title": "Panel Tests - Gauge Multi Series", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2alpha1.json index bd213346a6a..fe4271d08e7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2alpha1.json @@ -62,6 +62,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -151,6 +157,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -241,6 +253,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -320,6 +338,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -401,6 +425,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -480,6 +510,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -559,6 +595,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -639,6 +681,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -730,6 +778,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -927,6 +981,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -1006,6 +1066,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -1085,6 +1151,12 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -1429,5 +1501,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2beta1.json index 4e6d53c09ab..261cd5228db 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests.v42.v2beta1.json @@ -67,6 +67,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -159,6 +165,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -252,6 +264,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -334,6 +352,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -418,6 +442,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -500,6 +530,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -582,6 +618,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -665,6 +707,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -759,6 +807,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -961,6 +1015,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -1043,6 +1103,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -1125,6 +1191,12 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "gauge", + "originalOptions": { + "nullPointMode": "null" + } + }, "baseColor": "#299c46", "reduceOptions": { "calcs": [ @@ -1469,5 +1541,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v1beta1.json index 3084bbd32ea..66ce1cd0f3a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v1beta1.json @@ -77,14 +77,13 @@ "id": 1, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": false, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -156,14 +155,13 @@ "id": 4, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -235,14 +233,13 @@ "id": 3, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -277,85 +274,6 @@ "title": "Center and bar glow", "type": "radialbar" }, - { - "datasource": { - "type": "grafana-testdata-datasource" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 4, - "x": 12, - "y": 1 - }, - "id": 5, - "maxDataPoints": 20, - "options": { - "barWidthFactor": 0.4, - "effects": { - "barGlow": true, - "centerGlow": true, - "rounded": true, - "spotlight": true - }, - "gradient": "none", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "segmentCount": 1, - "segmentSpacing": 0.3, - "shape": "circle", - "showThresholdLabels": false, - "showThresholdMarkers": false, - "sparkline": false - }, - "pluginVersion": "13.0.0-pre", - "targets": [ - { - "alias": "1", - "datasource": { - "type": "grafana-testdata-datasource" - }, - "max": 100, - "min": 1, - "noise": 22, - "refId": "A", - "scenarioId": "random_walk", - "spread": 22, - "startValue": 1 - } - ], - "title": "Spotlight", - "type": "radialbar" - }, { "datasource": { "type": "grafana-testdata-datasource" @@ -393,14 +311,13 @@ "id": 8, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -472,14 +389,13 @@ "id": 22, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -551,14 +467,13 @@ "id": 23, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -643,14 +558,13 @@ "id": 18, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.1, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -722,14 +636,13 @@ "id": 19, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.32, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -801,14 +714,13 @@ "id": 20, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.57, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -880,14 +792,13 @@ "id": 21, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.8, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -976,14 +887,13 @@ "id": 25, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1055,14 +965,13 @@ "id": 26, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1134,14 +1043,13 @@ "id": 29, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1213,14 +1121,13 @@ "id": 30, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1292,14 +1199,13 @@ "id": 28, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1388,14 +1294,13 @@ "id": 32, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1471,14 +1376,13 @@ "id": 34, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1554,14 +1458,13 @@ "id": 33, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1645,16 +1548,16 @@ "id": 9, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "endpointMarker": "glow", "glow": "both", - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1668,8 +1571,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1731,16 +1633,15 @@ "id": 11, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1754,8 +1655,7 @@ "shape": "gauge", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": true, - "spotlight": true + "sparkline": true }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1831,16 +1731,15 @@ "id": 13, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1854,8 +1753,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1918,17 +1816,15 @@ "id": 14, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "sparkline": false, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1942,8 +1838,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2005,16 +1900,15 @@ "id": 15, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.84, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2028,8 +1922,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2091,16 +1984,15 @@ "id": 16, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.66, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2114,8 +2006,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2alpha1.json index 5b5c3951ad8..95850646c59 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2alpha1.json @@ -73,14 +73,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": false, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -165,16 +164,15 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -188,8 +186,7 @@ "shape": "gauge", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": true, - "spotlight": true + "sparkline": true }, "fieldConfig": { "defaults": { @@ -262,16 +259,15 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -285,8 +281,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -360,17 +355,15 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "sparkline": false, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -384,8 +377,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -459,16 +451,15 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.84, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -482,8 +473,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -556,16 +546,15 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.66, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -579,8 +568,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -653,14 +641,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.1, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -745,14 +732,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.32, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -837,14 +823,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.57, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -929,14 +914,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.8, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1021,14 +1005,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1113,14 +1096,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1201,14 +1183,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1293,14 +1274,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1385,14 +1365,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1477,14 +1456,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1573,14 +1551,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1661,14 +1638,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1753,14 +1729,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1849,14 +1824,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1945,14 +1919,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2045,106 +2018,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "segmentCount": 1, - "segmentSpacing": 0.3, - "shape": "circle", - "showThresholdLabels": false, - "showThresholdMarkers": false, - "sparkline": false - }, - "fieldConfig": { - "defaults": { - "min": 0, - "max": 100, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "value": 0, - "color": "green" - }, - { - "value": 80, - "color": "red" - } - ] - }, - "color": { - "mode": "thresholds" - } - }, - "overrides": [] - } - } - } - } - }, - "panel-5": { - "kind": "Panel", - "spec": { - "id": 5, - "title": "Spotlight", - "description": "", - "links": [], - "data": { - "kind": "QueryGroup", - "spec": { - "queries": [ - { - "kind": "PanelQuery", - "spec": { - "query": { - "kind": "grafana-testdata-datasource", - "spec": { - "alias": "1", - "max": 100, - "min": 1, - "noise": 22, - "scenarioId": "random_walk", - "spread": 22, - "startValue": 1 - } - }, - "refId": "A", - "hidden": false - } - } - ], - "transformations": [], - "queryOptions": { - "maxDataPoints": 20 - } - } - }, - "vizConfig": { - "kind": "radialbar", - "spec": { - "pluginVersion": "13.0.0-pre", - "options": { - "barWidthFactor": 0.4, - "effects": { - "barGlow": true, - "centerGlow": true, - "rounded": true, - "spotlight": true - }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2229,14 +2109,13 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2321,16 +2200,16 @@ "spec": { "pluginVersion": "13.0.0-pre", "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "endpointMarker": "glow", "glow": "both", - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2344,8 +2223,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -2429,19 +2307,6 @@ } } }, - { - "kind": "GridLayoutItem", - "spec": { - "x": 12, - "y": 0, - "width": 4, - "height": 6, - "element": { - "kind": "ElementReference", - "name": "panel-5" - } - } - }, { "kind": "GridLayoutItem", "spec": { @@ -2820,5 +2685,10 @@ "title": "Panel tests - Gauge (new)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2beta1.json index 24125f197c5..fda0d31e71b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_new.v42.v2beta1.json @@ -77,14 +77,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": false, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -172,16 +171,15 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -195,8 +193,7 @@ "shape": "gauge", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": true, - "spotlight": true + "sparkline": true }, "fieldConfig": { "defaults": { @@ -272,16 +269,15 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -295,8 +291,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -373,17 +368,15 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "sparkline": false, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -397,8 +390,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -475,16 +467,15 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.84, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -498,8 +489,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -575,16 +565,15 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.66, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -598,8 +587,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -675,14 +663,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.1, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -770,14 +757,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.32, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -865,14 +851,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.57, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -960,14 +945,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.8, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1055,14 +1039,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1150,14 +1133,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1241,14 +1223,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1336,14 +1317,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1431,14 +1411,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1526,14 +1505,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1625,14 +1603,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1716,14 +1693,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1811,14 +1787,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1910,14 +1885,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2009,14 +1983,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2112,109 +2085,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "segmentCount": 1, - "segmentSpacing": 0.3, - "shape": "circle", - "showThresholdLabels": false, - "showThresholdMarkers": false, - "sparkline": false - }, - "fieldConfig": { - "defaults": { - "min": 0, - "max": 100, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "value": 0, - "color": "green" - }, - { - "value": 80, - "color": "red" - } - ] - }, - "color": { - "mode": "thresholds" - } - }, - "overrides": [] - } - } - } - } - }, - "panel-5": { - "kind": "Panel", - "spec": { - "id": 5, - "title": "Spotlight", - "description": "", - "links": [], - "data": { - "kind": "QueryGroup", - "spec": { - "queries": [ - { - "kind": "PanelQuery", - "spec": { - "query": { - "kind": "DataQuery", - "group": "grafana-testdata-datasource", - "version": "v0", - "spec": { - "alias": "1", - "max": 100, - "min": 1, - "noise": 22, - "scenarioId": "random_walk", - "spread": 22, - "startValue": 1 - } - }, - "refId": "A", - "hidden": false - } - } - ], - "transformations": [], - "queryOptions": { - "maxDataPoints": 20 - } - } - }, - "vizConfig": { - "kind": "VizConfig", - "group": "radialbar", - "version": "13.0.0-pre", - "spec": { - "options": { - "barWidthFactor": 0.4, - "effects": { - "barGlow": true, - "centerGlow": true, - "rounded": true, - "spotlight": true - }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2302,14 +2179,13 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2397,16 +2273,16 @@ "version": "13.0.0-pre", "spec": { "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "endpointMarker": "glow", "glow": "both", - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2420,8 +2296,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "fieldConfig": { "defaults": { @@ -2505,19 +2380,6 @@ } } }, - { - "kind": "GridLayoutItem", - "spec": { - "x": 12, - "y": 0, - "width": 4, - "height": 6, - "element": { - "kind": "ElementReference", - "name": "panel-5" - } - } - }, { "kind": "GridLayoutItem", "spec": { @@ -2896,5 +2758,10 @@ "title": "Panel tests - Gauge (new)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v1beta1.json index ddad9707104..2dddd657c5f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v1beta1.json @@ -961,10 +961,8 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2alpha1.json index b485fbf84ed..db19ac588c1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2alpha1.json @@ -864,10 +864,8 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1614,5 +1612,10 @@ "title": "Panel tests - Old gauge to new", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2beta1.json index 304058565f1..8ddc6feb297 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-gauge/v0alpha1.gauge_tests_old_to_new.v42.v2beta1.json @@ -901,10 +901,8 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1666,5 +1664,10 @@ "title": "Panel tests - Old gauge to new", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2alpha1.json index fe6b8e09647..8f6ae2065e2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2alpha1.json @@ -671,5 +671,10 @@ "title": "Geomap - color field Copy", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2beta1.json index ccd502e8e11..e567e6dbae2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-color-field.v42.v2beta1.json @@ -683,5 +683,10 @@ "title": "Geomap - color field Copy", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2alpha1.json index f55700a79cd..135c8d98558 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2alpha1.json @@ -201,5 +201,10 @@ "title": "Panel Tests - Geomap Photo Layer", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2beta1.json index 4a7594b73a9..ce7d1c02a17 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-photo-layer.v42.v2beta1.json @@ -205,5 +205,10 @@ "title": "Panel Tests - Geomap Photo Layer", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2alpha1.json index 92f520e0857..32cc829050d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2alpha1.json @@ -341,5 +341,10 @@ "title": "Panel Tests - Geomap Fit to Data - Multiple Layer Types", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2beta1.json index 82b86117485..758836fdd75 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-route-layer.v42.v2beta1.json @@ -347,5 +347,10 @@ "title": "Panel Tests - Geomap Fit to Data - Multiple Layer Types", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2alpha1.json index 87e64b32650..f6a93ab505e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2alpha1.json @@ -173,5 +173,10 @@ "title": "Panel Tests - Geomap geohash transformer", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2beta1.json index 5184ebb6680..376a2e0b52a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-spatial-operations-transformer.v42.v2beta1.json @@ -177,5 +177,10 @@ "title": "Panel Tests - Geomap geohash transformer", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2alpha1.json index 6ae35916b91..aecc89871f9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2alpha1.json @@ -457,5 +457,10 @@ "title": "Panel Tests - Geomap 9.1", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2beta1.json index a385b59567b..0bbab3d3711 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap-v91.v42.v2beta1.json @@ -467,5 +467,10 @@ "title": "Panel Tests - Geomap 9.1", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2alpha1.json index f7374506e86..d4c2a4a8145 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2alpha1.json @@ -538,5 +538,10 @@ "title": "Panel Tests - Geomap Multi Layers", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2beta1.json index b244899e6d4..4726ddb6e4b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.geomap_multi-layers.v42.v2beta1.json @@ -545,5 +545,10 @@ "title": "Panel Tests - Geomap Multi Layers", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2alpha1.json index 517c35c8e98..209afba2ff2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2alpha1.json @@ -594,5 +594,10 @@ "title": "Panel Tests - Geomap", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2beta1.json index 2d8549a8d89..4fdd338e7bd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-geomap/v0alpha1.panel-geomap.v42.v2beta1.json @@ -607,5 +607,10 @@ "title": "Panel Tests - Geomap", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2alpha1.json index 44ab8d372ff..ef393dae560 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2alpha1.json @@ -66,7 +66,68 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -114,7 +175,68 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "rgb(87, 186, 242)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 4, + "fillGradient": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -162,7 +284,68 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "rgb(48, 139, 237)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -210,7 +393,68 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decgbytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -310,5 +554,10 @@ "title": "Panel Tests - Graph - Gradient Area Fills", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2beta1.json index 6beb26d4e70..e6def19e038 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-gradient-area-fills.v42.v2beta1.json @@ -70,7 +70,68 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "fillGradient": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 0, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -120,7 +181,68 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "rgb(87, 186, 242)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 4, + "fillGradient": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -170,7 +292,68 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "rgb(48, 139, 237)" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -220,7 +403,68 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "red" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decgbytes", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -320,5 +564,10 @@ "title": "Panel Tests - Graph - Gradient Area Fills", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2alpha1.json index 4628e8234f0..6aab259eb23 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2alpha1.json @@ -63,6 +63,65 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -700,6 +759,65 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "celsius", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -971,5 +1089,10 @@ "title": "Panel Tests - shared tooltips", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2beta1.json index 540a9010d55..2ba9ec92cb6 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-shared-tooltips.v42.v2beta1.json @@ -67,6 +67,65 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -717,6 +776,65 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "celsius", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -990,5 +1108,10 @@ "title": "Panel Tests - shared tooltips", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2alpha1.json index 2dd4dd48907..894c33abef1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2alpha1.json @@ -61,7 +61,78 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "gray", + "fill": true, + "fillColor": "rgba(255, 255, 255, 0.03)", + "from": "08:30", + "fromDayOfWeek": 1, + "line": false, + "lineColor": "rgba(255, 255, 255, 0.2)", + "op": "time", + "to": "16:45", + "toDayOfWeek": 5 + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -104,7 +175,140 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "#d683ce" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 0.5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(255, 0, 0, 0.22)", + "from": "", + "fromDayOfWeek": 1, + "line": true, + "lineColor": "rgba(255, 0, 0, 0.32)", + "op": "time", + "to": "", + "toDayOfWeek": 1 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(255, 127, 0, 0.22)", + "fromDayOfWeek": 2, + "line": true, + "lineColor": "rgba(255, 127, 0, 0.32)", + "op": "time", + "toDayOfWeek": 2 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(255, 255, 0, 0.22)", + "fromDayOfWeek": 3, + "line": true, + "lineColor": "rgba(255, 255, 0, 0.22)", + "op": "time", + "toDayOfWeek": 3 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(0, 255, 0, 0.22)", + "fromDayOfWeek": 4, + "line": true, + "lineColor": "rgba(0, 255, 0, 0.32)", + "op": "time", + "toDayOfWeek": 4 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(0, 0, 255, 0.22)", + "fromDayOfWeek": 5, + "line": true, + "lineColor": "rgba(0, 0, 255, 0.32)", + "op": "time", + "toDayOfWeek": 5 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(75, 0, 130, 0.22)", + "fromDayOfWeek": 6, + "line": true, + "lineColor": "rgba(75, 0, 130, 0.32)", + "op": "time", + "toDayOfWeek": 6 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(148, 0, 211, 0.22)", + "fromDayOfWeek": 7, + "line": true, + "lineColor": "rgba(148, 0, 211, 0.32)", + "op": "time", + "toDayOfWeek": 7 + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -150,7 +354,78 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "red", + "fill": true, + "fillColor": "rgba(255, 255, 255, 0.03)", + "from": "20:00", + "fromDayOfWeek": 7, + "line": false, + "lineColor": "rgba(255, 255, 255, 0.2)", + "op": "time", + "to": "23:00", + "toDayOfWeek": 7 + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -196,7 +471,73 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "red", + "fill": false, + "from": "05:00", + "line": true, + "op": "time" + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -238,7 +579,76 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "gray", + "fill": true, + "fillColor": "rgba(234, 112, 112, 0.12)", + "from": "22:00", + "line": false, + "lineColor": "rgba(237, 46, 24, 0.60)", + "op": "time", + "to": "00:30" + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -351,5 +761,10 @@ "title": "Panel Tests - Graph Time Regions", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2beta1.json index 7a1aa009f08..69aceb23017 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph-time-regions.v42.v2beta1.json @@ -66,7 +66,78 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "gray", + "fill": true, + "fillColor": "rgba(255, 255, 255, 0.03)", + "from": "08:30", + "fromDayOfWeek": 1, + "line": false, + "lineColor": "rgba(255, 255, 255, 0.2)", + "op": "time", + "to": "16:45", + "toDayOfWeek": 5 + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -112,7 +183,140 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": { + "A-series": "#d683ce" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 0.5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(255, 0, 0, 0.22)", + "from": "", + "fromDayOfWeek": 1, + "line": true, + "lineColor": "rgba(255, 0, 0, 0.32)", + "op": "time", + "to": "", + "toDayOfWeek": 1 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(255, 127, 0, 0.22)", + "fromDayOfWeek": 2, + "line": true, + "lineColor": "rgba(255, 127, 0, 0.32)", + "op": "time", + "toDayOfWeek": 2 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(255, 255, 0, 0.22)", + "fromDayOfWeek": 3, + "line": true, + "lineColor": "rgba(255, 255, 0, 0.22)", + "op": "time", + "toDayOfWeek": 3 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(0, 255, 0, 0.22)", + "fromDayOfWeek": 4, + "line": true, + "lineColor": "rgba(0, 255, 0, 0.32)", + "op": "time", + "toDayOfWeek": 4 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(0, 0, 255, 0.22)", + "fromDayOfWeek": 5, + "line": true, + "lineColor": "rgba(0, 0, 255, 0.32)", + "op": "time", + "toDayOfWeek": 5 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(75, 0, 130, 0.22)", + "fromDayOfWeek": 6, + "line": true, + "lineColor": "rgba(75, 0, 130, 0.32)", + "op": "time", + "toDayOfWeek": 6 + }, + { + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(148, 0, 211, 0.22)", + "fromDayOfWeek": 7, + "line": true, + "lineColor": "rgba(148, 0, 211, 0.32)", + "op": "time", + "toDayOfWeek": 7 + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -161,7 +365,78 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "red", + "fill": true, + "fillColor": "rgba(255, 255, 255, 0.03)", + "from": "20:00", + "fromDayOfWeek": 7, + "line": false, + "lineColor": "rgba(255, 255, 255, 0.2)", + "op": "time", + "to": "23:00", + "toDayOfWeek": 7 + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -210,7 +485,73 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "red", + "fill": false, + "from": "05:00", + "line": true, + "op": "time" + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -255,7 +596,76 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [ + { + "colorMode": "gray", + "fill": true, + "fillColor": "rgba(234, 112, 112, 0.12)", + "from": "22:00", + "line": false, + "lineColor": "rgba(237, 46, 24, 0.60)", + "op": "time", + "to": "00:30" + } + ], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -368,5 +778,10 @@ "title": "Panel Tests - Graph Time Regions", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2alpha1.json index e251ae6c6db..fa1ae3a63d8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2alpha1.json @@ -62,7 +62,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -106,7 +166,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -183,7 +303,72 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "zindex": -3 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -227,7 +412,17 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Should be a long line connecting the null region in the `connected` mode, and in zero it should just be a line with zero value at the null points. ", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -271,7 +466,17 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Stacking values on top of nulls, should treat the null values as zero. ", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -315,7 +520,17 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Stacking when all values are null should leave a gap in the graph", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -404,7 +619,66 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -583,7 +857,66 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -672,7 +1005,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -881,7 +1274,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -925,7 +1378,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -969,7 +1482,66 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1030,7 +1602,72 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "C-series", + "steppedLine": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1074,7 +1711,17 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Left is showing null between values for a normal line graph and staircase graph. Orphaned data points should be rendered as points", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1118,7 +1765,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1164,7 +1871,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1223,7 +1990,74 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "Percent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "label": "Pressure", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1267,7 +2101,17 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Just verify that the tooltip time has millisecond resolution ", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1311,7 +2155,17 @@ "kind": "text", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Verify that axis labels look ok", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1355,7 +2209,67 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1431,7 +2345,72 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "zindex": -3 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1752,5 +2731,10 @@ "title": "Panel Tests - Graph", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2beta1.json index a87d37bc099..5a580bbaa59 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_tests.v42.v2beta1.json @@ -67,7 +67,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -114,7 +174,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -198,7 +318,72 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "zindex": -3 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -244,7 +429,17 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Should be a long line connecting the null region in the `connected` mode, and in zero it should just be a line with zero value at the null points. ", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -290,7 +485,17 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Stacking values on top of nulls, should treat the null values as zero. ", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -336,7 +541,17 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Stacking when all values are null should leave a gap in the graph", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -434,7 +649,66 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -634,7 +908,66 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -732,7 +1065,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -966,7 +1359,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1013,7 +1466,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1060,7 +1573,66 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1126,7 +1698,72 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "C-series", + "steppedLine": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1172,7 +1809,17 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Left is showing null between values for a normal line graph and staircase graph. Orphaned data points should be rendered as points", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1219,7 +1866,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1268,7 +1975,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1332,7 +2099,74 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "Percent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "label": "Pressure", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1378,7 +2212,17 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Just verify that the tooltip time has millisecond resolution ", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1424,7 +2268,17 @@ "group": "text", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "text", + "originalOptions": { + "content": "Verify that axis labels look ok", + "editable": true, + "error": false, + "mode": "markdown" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1471,7 +2325,67 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1554,7 +2468,72 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "zindex": -3 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1875,5 +2854,10 @@ "title": "Panel Tests - Graph", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2alpha1.json index 33b1bd246ee..f060ff213d2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2alpha1.json @@ -66,6 +66,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -115,6 +175,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -164,6 +284,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -213,6 +391,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -262,6 +500,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -311,6 +609,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -360,6 +716,66 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -409,6 +825,64 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -458,6 +932,65 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -623,5 +1156,10 @@ "title": "Panel Tests - Graph - Y axis ticks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2beta1.json index bf16659bc49..8202a6a7dd7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-graph/v0alpha1.graph_y_axis.v42.v2beta1.json @@ -70,6 +70,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": "", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -121,6 +181,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -172,6 +292,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -223,6 +401,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -274,6 +512,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -325,6 +623,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -376,6 +732,66 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "max": "10000", + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -427,6 +843,64 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -478,6 +952,65 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "min": "0", + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -643,5 +1176,10 @@ "title": "Panel Tests - Graph - Y axis ticks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2alpha1.json index a5567148d48..fb399db27f9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2alpha1.json @@ -1113,5 +1113,10 @@ "title": "Heatmap calculate (log)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2beta1.json index 32816087c1d..1721f0b1c1f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-calculate-log.v42.v2beta1.json @@ -1133,5 +1133,10 @@ "title": "Heatmap calculate (log)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2alpha1.json index 69764686c12..8225aec6834 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2alpha1.json @@ -74,7 +74,44 @@ "kind": "heatmap", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateViridis", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "tooltipDecimals": 4, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 2, + "format": "areaM2", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -116,7 +153,46 @@ "kind": "heatmap", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": { + "cardRound": 50 + }, + "color": { + "cardColor": "#1F60C4", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "mode": "opacity" + }, + "dataFormat": "tsbuckets", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": false + }, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 1, + "format": "kwatt", + "logBase": 1, + "show": true, + "width": "100" + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -158,7 +234,44 @@ "kind": "heatmap", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#1F60C4", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "mode": "opacity" + }, + "dataFormat": "tsbuckets", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": true, + "tooltip": { + "show": true, + "showHistogram": false + }, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 1, + "format": "kwatt", + "logBase": 1, + "show": true, + "width": "100" + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -204,7 +317,46 @@ "kind": "heatmap", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateViridis", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "tooltipDecimals": 4, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 2, + "format": "areaM2", + "logBase": 1, + "max": "50", + "min": "20", + "show": true + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -246,7 +398,44 @@ "kind": "heatmap", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateBuGn", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "xAxis": { + "show": true + }, + "xBucketNumber": 10, + "yAxis": { + "format": "short", + "logBase": 2, + "show": true, + "splitFactor": 2 + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -288,7 +477,44 @@ "kind": "heatmap", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateBuGn", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "xAxis": { + "show": true + }, + "xBucketNumber": 10, + "yAxis": { + "format": "short", + "logBase": 10, + "show": true, + "splitFactor": 5 + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -414,5 +640,10 @@ "title": "Legacy heatmap", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2beta1.json index 7450f5af8ed..d7ec2abb5e8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-legacy.v42.v2beta1.json @@ -78,7 +78,44 @@ "group": "heatmap", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateViridis", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "tooltipDecimals": 4, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 2, + "format": "areaM2", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -123,7 +160,46 @@ "group": "heatmap", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": { + "cardRound": 50 + }, + "color": { + "cardColor": "#1F60C4", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "mode": "opacity" + }, + "dataFormat": "tsbuckets", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": false + }, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 1, + "format": "kwatt", + "logBase": 1, + "show": true, + "width": "100" + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -168,7 +244,44 @@ "group": "heatmap", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#1F60C4", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "mode": "opacity" + }, + "dataFormat": "tsbuckets", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": true, + "tooltip": { + "show": true, + "showHistogram": false + }, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 1, + "format": "kwatt", + "logBase": 1, + "show": true, + "width": "100" + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -216,7 +329,46 @@ "group": "heatmap", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateViridis", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "tooltipDecimals": 4, + "xAxis": { + "show": true + }, + "yAxis": { + "decimals": 2, + "format": "areaM2", + "logBase": 1, + "max": "50", + "min": "20", + "show": true + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -261,7 +413,44 @@ "group": "heatmap", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateBuGn", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "xAxis": { + "show": true + }, + "xBucketNumber": 10, + "yAxis": { + "format": "short", + "logBase": 2, + "show": true, + "splitFactor": 2 + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -306,7 +495,44 @@ "group": "heatmap", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateBuGn", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": true, + "highlightCards": true, + "legend": { + "show": true + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": true + }, + "xAxis": { + "show": true + }, + "xBucketNumber": 10, + "yAxis": { + "format": "short", + "logBase": 10, + "show": true, + "splitFactor": 5 + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -432,5 +658,10 @@ "title": "Legacy heatmap", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2alpha1.json index fdcb368edc4..2eb67e36f2f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2alpha1.json @@ -542,5 +542,10 @@ "title": "Heatmap X axis", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2beta1.json index b6d51918cbc..acba4cedbc2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-heatmap/v0alpha1.heatmap-x.v42.v2beta1.json @@ -554,5 +554,10 @@ "title": "Heatmap X axis", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2alpha1.json index cc15b1c4c91..57fbcad9d99 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2alpha1.json @@ -1243,5 +1243,10 @@ "title": "Panel Tests - Histogram", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2beta1.json index 81e56c3d318..5b2ee8d8df2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-histogram/v0alpha1.histogram_tests.v42.v2beta1.json @@ -1276,5 +1276,10 @@ "title": "Panel Tests - Histogram", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2alpha1.json index 2efffd9390c..dc0aab46631 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2alpha1.json @@ -109,6 +109,65 @@ "spec": { "pluginVersion": "7.4.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -193,5 +252,10 @@ "title": "Panel - Panel Library", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2beta1.json index 20438d25434..50419f5a194 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-library/v0alpha1.panel-library.v42.v2beta1.json @@ -113,6 +113,65 @@ "version": "7.4.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -197,5 +256,10 @@ "title": "Panel - Panel Library", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2alpha1.json index 742bed31cf6..84c03baac66 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2alpha1.json @@ -770,5 +770,10 @@ "title": "Panel Tests - Pie chart", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2beta1.json index b79118ec1bb..4e946c6aee9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-piechart/v0alpha1.panel_test_piechart.v42.v2beta1.json @@ -786,5 +786,10 @@ "title": "Panel Tests - Pie chart", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2alpha1.json index 97d355f227a..636612934c4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2alpha1.json @@ -119,7 +119,1073 @@ "kind": "grafana-polystat-panel", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-polystat-panel", + "originalOptions": { + "animationModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "d3DivId": "d3_svg_2", + "decimals": 2, + "displayModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "fontSizes": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70 + ], + "fontTypes": [ + "Open Sans", + "Arial", + "Avant Garde", + "Bookman", + "Consolas", + "Courier", + "Courier New", + "Futura", + "Garamond", + "Helvetica", + "Palatino", + "Times", + "Times New Roman", + "Verdana" + ], + "format": "none", + "notcolors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "operatorName": "avg", + "operatorOptions": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Count", + "value": "count" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Delta", + "value": "delta" + }, + { + "text": "Difference", + "value": "diff" + }, + { + "text": "First", + "value": "first" + }, + { + "text": "Log Min", + "value": "logmin" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Min", + "value": "min" + }, + { + "text": "Name", + "value": "name" + }, + { + "text": "Time of Last Point", + "value": "last_time" + }, + { + "text": "Time Step", + "value": "time_step" + }, + { + "text": "Total", + "value": "total" + } + ], + "polystat": { + "animationSpeed": 2500, + "columnAutoSize": true, + "columns": 1, + "defaultClickThrough": "", + "defaultClickThroughSanitize": true, + "displayLimit": 100, + "fontAutoScale": true, + "fontSize": 12, + "globalDisplayMode": "all", + "globalOperatorName": "avg", + "gradientEnabled": true, + "hexagonSortByDirection": "asc", + "hexagonSortByField": "name", + "maxMetrics": 0, + "polygonBorderColor": "black", + "polygonBorderSize": 2, + "radius": "", + "radiusAutoSize": true, + "rowAutoSize": true, + "rows": 1, + "shape": "hexagon_pointed_top", + "tooltipDisplayMode": "all", + "tooltipDisplayTextTriggeredEmpty": "OK", + "tooltipFontSize": 12, + "tooltipFontType": "Open Sans", + "tooltipPrimarySortDirection": "desc", + "tooltipPrimarySortField": "thresholdLevel", + "tooltipSecondarySortDirection": "desc", + "tooltipSecondarySortField": "value", + "tooltipTimestampEnabled": true + }, + "savedComposites": [], + "savedOverrides": [], + "shapes": [ + { + "text": "Hexagon Pointed Top", + "value": "hexagon_pointed_top" + }, + { + "text": "Hexagon Flat Top", + "value": "hexagon_flat_top" + }, + { + "text": "Circle", + "value": "circle" + }, + { + "text": "Cross", + "value": "cross" + }, + { + "text": "Diamond", + "value": "diamond" + }, + { + "text": "Square", + "value": "square" + }, + { + "text": "Star", + "value": "star" + }, + { + "text": "Triangle", + "value": "triangle" + }, + { + "text": "Wye", + "value": "wye" + } + ], + "sortDirections": [ + { + "text": "Ascending", + "value": "asc" + }, + { + "text": "Descending", + "value": "desc" + } + ], + "sortFields": [ + { + "text": "Name", + "value": "name" + }, + { + "text": "Threshold Level", + "value": "thresholdLevel" + }, + { + "text": "Value", + "value": "value" + } + ], + "svgContainer": {}, + "thresholdStates": [ + { + "text": "ok", + "value": 0 + }, + { + "text": "warning", + "value": 1 + }, + { + "text": "critical", + "value": 2 + }, + { + "text": "custom", + "value": 3 + } + ], + "unitFormats": [ + { + "submenu": [ + { + "text": "none", + "value": "none" + }, + { + "text": "short", + "value": "short" + }, + { + "text": "percent (0-100)", + "value": "percent" + }, + { + "text": "percent (0.0-1.0)", + "value": "percentunit" + }, + { + "text": "Humidity (%H)", + "value": "humidity" + }, + { + "text": "decibel", + "value": "dB" + }, + { + "text": "hexadecimal (0x)", + "value": "hex0x" + }, + { + "text": "hexadecimal", + "value": "hex" + }, + { + "text": "scientific notation", + "value": "sci" + }, + { + "text": "locale format", + "value": "locale" + } + ], + "text": "none" + }, + { + "submenu": [ + { + "text": "Dollars ($)", + "value": "currencyUSD" + }, + { + "text": "Pounds (£)", + "value": "currencyGBP" + }, + { + "text": "Euro (€)", + "value": "currencyEUR" + }, + { + "text": "Yen (¥)", + "value": "currencyJPY" + }, + { + "text": "Rubles (₽)", + "value": "currencyRUB" + }, + { + "text": "Hryvnias (₴)", + "value": "currencyUAH" + }, + { + "text": "Real (R$)", + "value": "currencyBRL" + }, + { + "text": "Danish Krone (kr)", + "value": "currencyDKK" + }, + { + "text": "Icelandic Króna (kr)", + "value": "currencyISK" + }, + { + "text": "Norwegian Krone (kr)", + "value": "currencyNOK" + }, + { + "text": "Swedish Krona (kr)", + "value": "currencySEK" + }, + { + "text": "Czech koruna (czk)", + "value": "currencyCZK" + }, + { + "text": "Swiss franc (CHF)", + "value": "currencyCHF" + }, + { + "text": "Polish Złoty (PLN)", + "value": "currencyPLN" + }, + { + "text": "Bitcoin (฿)", + "value": "currencyBTC" + }, + { + "text": "Vietnamese Dong (VND)", + "value": "currencyVND" + }, + { + "text": "Malaysian Ringgit (RM)", + "value": "currencyMYR" + }, + { + "text": "Bulgarian Lev (BGN)", + "value": "currencyBGN" + } + ], + "text": "currency" + }, + { + "submenu": [ + { + "text": "Hertz (1/s)", + "value": "hertz" + }, + { + "text": "nanoseconds (ns)", + "value": "ns" + }, + { + "text": "microseconds (µs)", + "value": "µs" + }, + { + "text": "milliseconds (ms)", + "value": "ms" + }, + { + "text": "seconds (s)", + "value": "s" + }, + { + "text": "minutes (m)", + "value": "m" + }, + { + "text": "hours (h)", + "value": "h" + }, + { + "text": "days (d)", + "value": "d" + }, + { + "text": "duration (ms)", + "value": "dtdurationms" + }, + { + "text": "duration (s)", + "value": "dtdurations" + }, + { + "text": "duration (hh:mm:ss)", + "value": "dthms" + }, + { + "text": "Timeticks (s/100)", + "value": "timeticks" + } + ], + "text": "time" + }, + { + "submenu": [ + { + "text": "YYYY-MM-DD HH:mm:ss", + "value": "dateTimeAsIso" + }, + { + "text": "DD/MM/YYYY h:mm:ss a", + "value": "dateTimeAsUS" + }, + { + "text": "From Now", + "value": "dateTimeFromNow" + } + ], + "text": "date \u0026 time" + }, + { + "submenu": [ + { + "text": "bits", + "value": "bits" + }, + { + "text": "bytes", + "value": "bytes" + }, + { + "text": "kibibytes", + "value": "kbytes" + }, + { + "text": "mebibytes", + "value": "mbytes" + }, + { + "text": "gibibytes", + "value": "gbytes" + } + ], + "text": "data (IEC)" + }, + { + "submenu": [ + { + "text": "bits", + "value": "decbits" + }, + { + "text": "bytes", + "value": "decbytes" + }, + { + "text": "kilobytes", + "value": "deckbytes" + }, + { + "text": "megabytes", + "value": "decmbytes" + }, + { + "text": "gigabytes", + "value": "decgbytes" + } + ], + "text": "data (Metric)" + }, + { + "submenu": [ + { + "text": "packets/sec", + "value": "pps" + }, + { + "text": "bits/sec", + "value": "bps" + }, + { + "text": "bytes/sec", + "value": "Bps" + }, + { + "text": "kilobits/sec", + "value": "Kbits" + }, + { + "text": "kilobytes/sec", + "value": "KBs" + }, + { + "text": "megabits/sec", + "value": "Mbits" + }, + { + "text": "megabytes/sec", + "value": "MBs" + }, + { + "text": "gigabytes/sec", + "value": "GBs" + }, + { + "text": "gigabits/sec", + "value": "Gbits" + } + ], + "text": "data rate" + }, + { + "submenu": [ + { + "text": "hashes/sec", + "value": "Hs" + }, + { + "text": "kilohashes/sec", + "value": "KHs" + }, + { + "text": "megahashes/sec", + "value": "MHs" + }, + { + "text": "gigahashes/sec", + "value": "GHs" + }, + { + "text": "terahashes/sec", + "value": "THs" + }, + { + "text": "petahashes/sec", + "value": "PHs" + }, + { + "text": "exahashes/sec", + "value": "EHs" + } + ], + "text": "hash rate" + }, + { + "submenu": [ + { + "text": "ops/sec (ops)", + "value": "ops" + }, + { + "text": "requests/sec (rps)", + "value": "reqps" + }, + { + "text": "reads/sec (rps)", + "value": "rps" + }, + { + "text": "writes/sec (wps)", + "value": "wps" + }, + { + "text": "I/O ops/sec (iops)", + "value": "iops" + }, + { + "text": "ops/min (opm)", + "value": "opm" + }, + { + "text": "requests/min (rpm)", + "value": "reqpm" + }, + { + "text": "reads/min (rpm)", + "value": "rpm" + }, + { + "text": "writes/min (wpm)", + "value": "wpm" + } + ], + "text": "throughput" + }, + { + "submenu": [ + { + "text": "millimetre (mm)", + "value": "lengthmm" + }, + { + "text": "meter (m)", + "value": "lengthm" + }, + { + "text": "inch (in)", + "value": "lengthin" + }, + { + "text": "feet (ft)", + "value": "lengthft" + }, + { + "text": "kilometer (km)", + "value": "lengthkm" + }, + { + "text": "mile (mi)", + "value": "lengthmi" + } + ], + "text": "length" + }, + { + "submenu": [ + { + "text": "Square Meters (m²)", + "value": "areaM2" + }, + { + "text": "Square Feet (ft²)", + "value": "areaF2" + }, + { + "text": "Square Miles (mi²)", + "value": "areaMI2" + } + ], + "text": "area" + }, + { + "submenu": [ + { + "text": "milligram (mg)", + "value": "massmg" + }, + { + "text": "gram (g)", + "value": "massg" + }, + { + "text": "pound (lb)", + "value": "masslb" + }, + { + "text": "kilogram (kg)", + "value": "masskg" + }, + { + "text": "metric ton (t)", + "value": "masst" + } + ], + "text": "mass" + }, + { + "submenu": [ + { + "text": "metres/second (m/s)", + "value": "velocityms" + }, + { + "text": "kilometers/hour (km/h)", + "value": "velocitykmh" + }, + { + "text": "miles/hour (mph)", + "value": "velocitymph" + }, + { + "text": "knot (kn)", + "value": "velocityknot" + } + ], + "text": "velocity" + }, + { + "submenu": [ + { + "text": "millilitre (mL)", + "value": "mlitre" + }, + { + "text": "litre (L)", + "value": "litre" + }, + { + "text": "cubic metre", + "value": "m3" + }, + { + "text": "Normal cubic metre", + "value": "Nm3" + }, + { + "text": "cubic decimetre", + "value": "dm3" + }, + { + "text": "gallons", + "value": "gallons" + } + ], + "text": "volume" + }, + { + "submenu": [ + { + "text": "Watt (W)", + "value": "watt" + }, + { + "text": "Kilowatt (kW)", + "value": "kwatt" + }, + { + "text": "Milliwatt (mW)", + "value": "mwatt" + }, + { + "text": "Watt per square metre (W/m²)", + "value": "Wm2" + }, + { + "text": "Volt-ampere (VA)", + "value": "voltamp" + }, + { + "text": "Kilovolt-ampere (kVA)", + "value": "kvoltamp" + }, + { + "text": "Volt-ampere reactive (var)", + "value": "voltampreact" + }, + { + "text": "Kilovolt-ampere reactive (kvar)", + "value": "kvoltampreact" + }, + { + "text": "Watt-hour (Wh)", + "value": "watth" + }, + { + "text": "Kilowatt-hour (kWh)", + "value": "kwatth" + }, + { + "text": "Kilowatt-min (kWm)", + "value": "kwattm" + }, + { + "text": "Joule (J)", + "value": "joule" + }, + { + "text": "Electron volt (eV)", + "value": "ev" + }, + { + "text": "Ampere (A)", + "value": "amp" + }, + { + "text": "Kiloampere (kA)", + "value": "kamp" + }, + { + "text": "Milliampere (mA)", + "value": "mamp" + }, + { + "text": "Volt (V)", + "value": "volt" + }, + { + "text": "Kilovolt (kV)", + "value": "kvolt" + }, + { + "text": "Millivolt (mV)", + "value": "mvolt" + }, + { + "text": "Decibel-milliwatt (dBm)", + "value": "dBm" + }, + { + "text": "Ohm (Ω)", + "value": "ohm" + }, + { + "text": "Lumens (Lm)", + "value": "lumens" + } + ], + "text": "energy" + }, + { + "submenu": [ + { + "text": "Celsius (°C)", + "value": "celsius" + }, + { + "text": "Fahrenheit (°F)", + "value": "fahrenheit" + }, + { + "text": "Kelvin (K)", + "value": "kelvin" + } + ], + "text": "temperature" + }, + { + "submenu": [ + { + "text": "Millibars", + "value": "pressurembar" + }, + { + "text": "Bars", + "value": "pressurebar" + }, + { + "text": "Kilobars", + "value": "pressurekbar" + }, + { + "text": "Hectopascals", + "value": "pressurehpa" + }, + { + "text": "Kilopascals", + "value": "pressurekpa" + }, + { + "text": "Inches of mercury", + "value": "pressurehg" + }, + { + "text": "PSI", + "value": "pressurepsi" + } + ], + "text": "pressure" + }, + { + "submenu": [ + { + "text": "Newton-meters (Nm)", + "value": "forceNm" + }, + { + "text": "Kilonewton-meters (kNm)", + "value": "forcekNm" + }, + { + "text": "Newtons (N)", + "value": "forceN" + }, + { + "text": "Kilonewtons (kN)", + "value": "forcekN" + } + ], + "text": "force" + }, + { + "submenu": [ + { + "text": "Gallons/min (gpm)", + "value": "flowgpm" + }, + { + "text": "Cubic meters/sec (cms)", + "value": "flowcms" + }, + { + "text": "Cubic feet/sec (cfs)", + "value": "flowcfs" + }, + { + "text": "Cubic feet/min (cfm)", + "value": "flowcfm" + }, + { + "text": "Litre/hour", + "value": "litreh" + }, + { + "text": "Litre/min (l/min)", + "value": "flowlpm" + }, + { + "text": "milliLitre/min (mL/min)", + "value": "flowmlpm" + } + ], + "text": "flow" + }, + { + "submenu": [ + { + "text": "Degrees (°)", + "value": "degree" + }, + { + "text": "Radians", + "value": "radian" + }, + { + "text": "Gradian", + "value": "grad" + } + ], + "text": "angle" + }, + { + "submenu": [ + { + "text": "Meters/sec²", + "value": "accMS2" + }, + { + "text": "Feet/sec²", + "value": "accFS2" + }, + { + "text": "G unit", + "value": "accG" + } + ], + "text": "acceleration" + }, + { + "submenu": [ + { + "text": "Becquerel (Bq)", + "value": "radbq" + }, + { + "text": "curie (Ci)", + "value": "radci" + }, + { + "text": "Gray (Gy)", + "value": "radgy" + }, + { + "text": "rad", + "value": "radrad" + }, + { + "text": "Sievert (Sv)", + "value": "radsv" + }, + { + "text": "rem", + "value": "radrem" + }, + { + "text": "Exposure (C/kg)", + "value": "radexpckg" + }, + { + "text": "roentgen (R)", + "value": "radr" + }, + { + "text": "Sievert/hour (Sv/h)", + "value": "radsvh" + } + ], + "text": "radiation" + }, + { + "submenu": [ + { + "text": "parts-per-million (ppm)", + "value": "ppm" + }, + { + "text": "parts-per-billion (ppb)", + "value": "conppb" + }, + { + "text": "nanogram per cubic metre (ng/m³)", + "value": "conngm3" + }, + { + "text": "nanogram per normal cubic metre (ng/Nm³)", + "value": "conngNm3" + }, + { + "text": "microgram per cubic metre (μg/m³)", + "value": "conμgm3" + }, + { + "text": "microgram per normal cubic metre (μg/Nm³)", + "value": "conμgNm3" + }, + { + "text": "milligram per cubic metre (mg/m³)", + "value": "conmgm3" + }, + { + "text": "milligram per normal cubic metre (mg/Nm³)", + "value": "conmgNm3" + }, + { + "text": "gram per cubic metre (g/m³)", + "value": "congm3" + }, + { + "text": "gram per normal cubic metre (g/Nm³)", + "value": "congNm3" + } + ], + "text": "concentration" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -228,7 +1294,1129 @@ "kind": "grafana-polystat-panel", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-polystat-panel", + "originalOptions": { + "animationModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "d3DivId": "d3_svg_4", + "decimals": 2, + "displayModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "fontSizes": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70 + ], + "fontTypes": [ + "Open Sans", + "Arial", + "Avant Garde", + "Bookman", + "Consolas", + "Courier", + "Courier New", + "Futura", + "Garamond", + "Helvetica", + "Palatino", + "Times", + "Times New Roman", + "Verdana" + ], + "format": "none", + "notcolors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "operatorName": "avg", + "operatorOptions": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Count", + "value": "count" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Delta", + "value": "delta" + }, + { + "text": "Difference", + "value": "diff" + }, + { + "text": "First", + "value": "first" + }, + { + "text": "Log Min", + "value": "logmin" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Min", + "value": "min" + }, + { + "text": "Name", + "value": "name" + }, + { + "text": "Time of Last Point", + "value": "last_time" + }, + { + "text": "Time Step", + "value": "time_step" + }, + { + "text": "Total", + "value": "total" + } + ], + "polystat": { + "animationSpeed": 2500, + "columnAutoSize": true, + "columns": "", + "defaultClickThrough": "", + "defaultClickThroughSanitize": true, + "displayLimit": 100, + "fontAutoScale": true, + "fontSize": 12, + "globalDisplayMode": "all", + "globalOperatorName": "avg", + "gradientEnabled": true, + "hexagonSortByDirection": "asc", + "hexagonSortByField": "name", + "maxMetrics": 0, + "polygonBorderColor": "black", + "polygonBorderSize": 2, + "radius": "", + "radiusAutoSize": true, + "rowAutoSize": true, + "rows": "", + "shape": "hexagon_pointed_top", + "tooltipDisplayMode": "all", + "tooltipDisplayTextTriggeredEmpty": "OK", + "tooltipFontSize": 12, + "tooltipFontType": "Open Sans", + "tooltipPrimarySortDirection": "desc", + "tooltipPrimarySortField": "thresholdLevel", + "tooltipSecondarySortDirection": "desc", + "tooltipSecondarySortField": "value", + "tooltipTimestampEnabled": true + }, + "savedComposites": [], + "savedOverrides": [], + "shapes": [ + { + "text": "Hexagon Pointed Top", + "value": "hexagon_pointed_top" + }, + { + "text": "Hexagon Flat Top", + "value": "hexagon_flat_top" + }, + { + "text": "Circle", + "value": "circle" + }, + { + "text": "Cross", + "value": "cross" + }, + { + "text": "Diamond", + "value": "diamond" + }, + { + "text": "Square", + "value": "square" + }, + { + "text": "Star", + "value": "star" + }, + { + "text": "Triangle", + "value": "triangle" + }, + { + "text": "Wye", + "value": "wye" + } + ], + "sortDirections": [ + { + "text": "Ascending", + "value": "asc" + }, + { + "text": "Descending", + "value": "desc" + } + ], + "sortFields": [ + { + "text": "Name", + "value": "name" + }, + { + "text": "Threshold Level", + "value": "thresholdLevel" + }, + { + "text": "Value", + "value": "value" + } + ], + "svgContainer": {}, + "thresholdStates": [ + { + "text": "ok", + "value": 0 + }, + { + "text": "warning", + "value": 1 + }, + { + "text": "critical", + "value": 2 + }, + { + "text": "custom", + "value": 3 + } + ], + "unitFormats": [ + { + "submenu": [ + { + "text": "none", + "value": "none" + }, + { + "text": "short", + "value": "short" + }, + { + "text": "percent (0-100)", + "value": "percent" + }, + { + "text": "percent (0.0-1.0)", + "value": "percentunit" + }, + { + "text": "Humidity (%H)", + "value": "humidity" + }, + { + "text": "decibel", + "value": "dB" + }, + { + "text": "hexadecimal (0x)", + "value": "hex0x" + }, + { + "text": "hexadecimal", + "value": "hex" + }, + { + "text": "scientific notation", + "value": "sci" + }, + { + "text": "locale format", + "value": "locale" + } + ], + "text": "none" + }, + { + "submenu": [ + { + "text": "Dollars ($)", + "value": "currencyUSD" + }, + { + "text": "Pounds (£)", + "value": "currencyGBP" + }, + { + "text": "Euro (€)", + "value": "currencyEUR" + }, + { + "text": "Yen (¥)", + "value": "currencyJPY" + }, + { + "text": "Rubles (₽)", + "value": "currencyRUB" + }, + { + "text": "Hryvnias (₴)", + "value": "currencyUAH" + }, + { + "text": "Real (R$)", + "value": "currencyBRL" + }, + { + "text": "Danish Krone (kr)", + "value": "currencyDKK" + }, + { + "text": "Icelandic Króna (kr)", + "value": "currencyISK" + }, + { + "text": "Norwegian Krone (kr)", + "value": "currencyNOK" + }, + { + "text": "Swedish Krona (kr)", + "value": "currencySEK" + }, + { + "text": "Czech koruna (czk)", + "value": "currencyCZK" + }, + { + "text": "Swiss franc (CHF)", + "value": "currencyCHF" + }, + { + "text": "Polish Złoty (PLN)", + "value": "currencyPLN" + }, + { + "text": "Bitcoin (฿)", + "value": "currencyBTC" + }, + { + "text": "Milli Bitcoin (mBTC)", + "value": "currencymBTC" + }, + { + "text": "Micro Bitcoin (μBTC)", + "value": "currencyμBTC" + }, + { + "text": "Vietnamese Dong (VND)", + "value": "currencyVND" + }, + { + "text": "Turkish Lira (₺)", + "value": "currencyTRY" + }, + { + "text": "Malaysian Ringgit (RM)", + "value": "currencyMYR" + }, + { + "text": "CFP franc (XPF)", + "value": "currencyXPF" + }, + { + "text": "Bulgarian Lev (BGN)", + "value": "currencyBGN" + } + ], + "text": "currency" + }, + { + "submenu": [ + { + "text": "Hertz (1/s)", + "value": "hertz" + }, + { + "text": "nanoseconds (ns)", + "value": "ns" + }, + { + "text": "microseconds (µs)", + "value": "µs" + }, + { + "text": "milliseconds (ms)", + "value": "ms" + }, + { + "text": "seconds (s)", + "value": "s" + }, + { + "text": "minutes (m)", + "value": "m" + }, + { + "text": "hours (h)", + "value": "h" + }, + { + "text": "days (d)", + "value": "d" + }, + { + "text": "duration (ms)", + "value": "dtdurationms" + }, + { + "text": "duration (s)", + "value": "dtdurations" + }, + { + "text": "duration (hh:mm:ss)", + "value": "dthms" + }, + { + "text": "Timeticks (s/100)", + "value": "timeticks" + } + ], + "text": "time" + }, + { + "submenu": [ + { + "text": "YYYY-MM-DD HH:mm:ss", + "value": "dateTimeAsIso" + }, + { + "text": "DD/MM/YYYY h:mm:ss a", + "value": "dateTimeAsUS" + }, + { + "text": "From Now", + "value": "dateTimeFromNow" + } + ], + "text": "date \u0026 time" + }, + { + "submenu": [ + { + "text": "bits", + "value": "bits" + }, + { + "text": "bytes", + "value": "bytes" + }, + { + "text": "kibibytes", + "value": "kbytes" + }, + { + "text": "mebibytes", + "value": "mbytes" + }, + { + "text": "gibibytes", + "value": "gbytes" + } + ], + "text": "data (IEC)" + }, + { + "submenu": [ + { + "text": "bits", + "value": "decbits" + }, + { + "text": "bytes", + "value": "decbytes" + }, + { + "text": "kilobytes", + "value": "deckbytes" + }, + { + "text": "megabytes", + "value": "decmbytes" + }, + { + "text": "gigabytes", + "value": "decgbytes" + } + ], + "text": "data (Metric)" + }, + { + "submenu": [ + { + "text": "packets/sec", + "value": "pps" + }, + { + "text": "bits/sec", + "value": "bps" + }, + { + "text": "bytes/sec", + "value": "Bps" + }, + { + "text": "kilobits/sec", + "value": "Kbits" + }, + { + "text": "kilobytes/sec", + "value": "KBs" + }, + { + "text": "megabits/sec", + "value": "Mbits" + }, + { + "text": "megabytes/sec", + "value": "MBs" + }, + { + "text": "gigabytes/sec", + "value": "GBs" + }, + { + "text": "gigabits/sec", + "value": "Gbits" + } + ], + "text": "data rate" + }, + { + "submenu": [ + { + "text": "hashes/sec", + "value": "Hs" + }, + { + "text": "kilohashes/sec", + "value": "KHs" + }, + { + "text": "megahashes/sec", + "value": "MHs" + }, + { + "text": "gigahashes/sec", + "value": "GHs" + }, + { + "text": "terahashes/sec", + "value": "THs" + }, + { + "text": "petahashes/sec", + "value": "PHs" + }, + { + "text": "exahashes/sec", + "value": "EHs" + } + ], + "text": "hash rate" + }, + { + "submenu": [ + { + "text": "counts/sec (cps)", + "value": "cps" + }, + { + "text": "ops/sec (ops)", + "value": "ops" + }, + { + "text": "requests/sec (rps)", + "value": "reqps" + }, + { + "text": "reads/sec (rps)", + "value": "rps" + }, + { + "text": "writes/sec (wps)", + "value": "wps" + }, + { + "text": "I/O ops/sec (iops)", + "value": "iops" + }, + { + "text": "events/sec (eps)", + "value": "eps" + }, + { + "text": "messages/sec (mps)", + "value": "mps" + }, + { + "text": "records/sec (rps)", + "value": "recps" + }, + { + "text": "rows/sec (rps)", + "value": "rowsps" + }, + { + "text": "counts/min (cpm)", + "value": "cpm" + }, + { + "text": "ops/min (opm)", + "value": "opm" + }, + { + "text": "requests/min (rpm)", + "value": "reqpm" + }, + { + "text": "reads/min (rpm)", + "value": "rpm" + }, + { + "text": "writes/min (wpm)", + "value": "wpm" + }, + { + "text": "events/min (epm)", + "value": "epm" + }, + { + "text": "messages/min (mpm)", + "value": "mpm" + }, + { + "text": "records/min (rpm)", + "value": "recpm" + }, + { + "text": "rows/min (rpm)", + "value": "rowspm" + } + ], + "text": "throughput" + }, + { + "submenu": [ + { + "text": "millimetre (mm)", + "value": "lengthmm" + }, + { + "text": "meter (m)", + "value": "lengthm" + }, + { + "text": "inch (in)", + "value": "lengthin" + }, + { + "text": "feet (ft)", + "value": "lengthft" + }, + { + "text": "kilometer (km)", + "value": "lengthkm" + }, + { + "text": "mile (mi)", + "value": "lengthmi" + } + ], + "text": "length" + }, + { + "submenu": [ + { + "text": "Square Meters (m²)", + "value": "areaM2" + }, + { + "text": "Square Feet (ft²)", + "value": "areaF2" + }, + { + "text": "Square Miles (mi²)", + "value": "areaMI2" + } + ], + "text": "area" + }, + { + "submenu": [ + { + "text": "milligram (mg)", + "value": "massmg" + }, + { + "text": "gram (g)", + "value": "massg" + }, + { + "text": "pound (lb)", + "value": "masslb" + }, + { + "text": "kilogram (kg)", + "value": "masskg" + }, + { + "text": "metric ton (t)", + "value": "masst" + } + ], + "text": "mass" + }, + { + "submenu": [ + { + "text": "metres/second (m/s)", + "value": "velocityms" + }, + { + "text": "kilometers/hour (km/h)", + "value": "velocitykmh" + }, + { + "text": "miles/hour (mph)", + "value": "velocitymph" + }, + { + "text": "knot (kn)", + "value": "velocityknot" + } + ], + "text": "velocity" + }, + { + "submenu": [ + { + "text": "millilitre (mL)", + "value": "mlitre" + }, + { + "text": "litre (L)", + "value": "litre" + }, + { + "text": "cubic metre", + "value": "m3" + }, + { + "text": "Normal cubic metre", + "value": "Nm3" + }, + { + "text": "cubic decimetre", + "value": "dm3" + }, + { + "text": "gallons", + "value": "gallons" + } + ], + "text": "volume" + }, + { + "submenu": [ + { + "text": "Watt (W)", + "value": "watt" + }, + { + "text": "Kilowatt (kW)", + "value": "kwatt" + }, + { + "text": "Milliwatt (mW)", + "value": "mwatt" + }, + { + "text": "Watt per square metre (W/m²)", + "value": "Wm2" + }, + { + "text": "Volt-Ampere (VA)", + "value": "voltamp" + }, + { + "text": "Kilovolt-Ampere (kVA)", + "value": "kvoltamp" + }, + { + "text": "Volt-Ampere reactive (VAr)", + "value": "voltampreact" + }, + { + "text": "Kilovolt-Ampere reactive (kVAr)", + "value": "kvoltampreact" + }, + { + "text": "Watt-hour (Wh)", + "value": "watth" + }, + { + "text": "Kilowatt-hour (kWh)", + "value": "kwatth" + }, + { + "text": "Kilowatt-min (kWm)", + "value": "kwattm" + }, + { + "text": "Joule (J)", + "value": "joule" + }, + { + "text": "Electron volt (eV)", + "value": "ev" + }, + { + "text": "Ampere (A)", + "value": "amp" + }, + { + "text": "Kiloampere (kA)", + "value": "kamp" + }, + { + "text": "Milliampere (mA)", + "value": "mamp" + }, + { + "text": "Volt (V)", + "value": "volt" + }, + { + "text": "Kilovolt (kV)", + "value": "kvolt" + }, + { + "text": "Millivolt (mV)", + "value": "mvolt" + }, + { + "text": "Decibel-milliwatt (dBm)", + "value": "dBm" + }, + { + "text": "Ohm (Ω)", + "value": "ohm" + }, + { + "text": "Lumens (Lm)", + "value": "lumens" + } + ], + "text": "energy" + }, + { + "submenu": [ + { + "text": "Celsius (°C)", + "value": "celsius" + }, + { + "text": "Fahrenheit (°F)", + "value": "fahrenheit" + }, + { + "text": "Kelvin (K)", + "value": "kelvin" + } + ], + "text": "temperature" + }, + { + "submenu": [ + { + "text": "Millibars", + "value": "pressurembar" + }, + { + "text": "Bars", + "value": "pressurebar" + }, + { + "text": "Kilobars", + "value": "pressurekbar" + }, + { + "text": "Hectopascals", + "value": "pressurehpa" + }, + { + "text": "Kilopascals", + "value": "pressurekpa" + }, + { + "text": "Inches of mercury", + "value": "pressurehg" + }, + { + "text": "PSI", + "value": "pressurepsi" + } + ], + "text": "pressure" + }, + { + "submenu": [ + { + "text": "Newton-meters (Nm)", + "value": "forceNm" + }, + { + "text": "Kilonewton-meters (kNm)", + "value": "forcekNm" + }, + { + "text": "Newtons (N)", + "value": "forceN" + }, + { + "text": "Kilonewtons (kN)", + "value": "forcekN" + } + ], + "text": "force" + }, + { + "submenu": [ + { + "text": "Gallons/min (gpm)", + "value": "flowgpm" + }, + { + "text": "Cubic meters/sec (cms)", + "value": "flowcms" + }, + { + "text": "Cubic feet/sec (cfs)", + "value": "flowcfs" + }, + { + "text": "Cubic feet/min (cfm)", + "value": "flowcfm" + }, + { + "text": "Litre/hour", + "value": "litreh" + }, + { + "text": "Litre/min (l/min)", + "value": "flowlpm" + }, + { + "text": "milliLitre/min (mL/min)", + "value": "flowmlpm" + } + ], + "text": "flow" + }, + { + "submenu": [ + { + "text": "Degrees (°)", + "value": "degree" + }, + { + "text": "Radians", + "value": "radian" + }, + { + "text": "Gradian", + "value": "grad" + } + ], + "text": "angle" + }, + { + "submenu": [ + { + "text": "Meters/sec²", + "value": "accMS2" + }, + { + "text": "Feet/sec²", + "value": "accFS2" + }, + { + "text": "G unit", + "value": "accG" + } + ], + "text": "acceleration" + }, + { + "submenu": [ + { + "text": "Becquerel (Bq)", + "value": "radbq" + }, + { + "text": "curie (Ci)", + "value": "radci" + }, + { + "text": "Gray (Gy)", + "value": "radgy" + }, + { + "text": "rad", + "value": "radrad" + }, + { + "text": "Sievert (Sv)", + "value": "radsv" + }, + { + "text": "rem", + "value": "radrem" + }, + { + "text": "Exposure (C/kg)", + "value": "radexpckg" + }, + { + "text": "roentgen (R)", + "value": "radr" + }, + { + "text": "Sievert/hour (Sv/h)", + "value": "radsvh" + } + ], + "text": "radiation" + }, + { + "submenu": [ + { + "text": "parts-per-million (ppm)", + "value": "ppm" + }, + { + "text": "parts-per-billion (ppb)", + "value": "conppb" + }, + { + "text": "nanogram per cubic metre (ng/m³)", + "value": "conngm3" + }, + { + "text": "nanogram per normal cubic metre (ng/Nm³)", + "value": "conngNm3" + }, + { + "text": "microgram per cubic metre (μg/m³)", + "value": "conμgm3" + }, + { + "text": "microgram per normal cubic metre (μg/Nm³)", + "value": "conμgNm3" + }, + { + "text": "milligram per cubic metre (mg/m³)", + "value": "conmgm3" + }, + { + "text": "milligram per normal cubic metre (mg/Nm³)", + "value": "conmgNm3" + }, + { + "text": "gram per cubic metre (g/m³)", + "value": "congm3" + }, + { + "text": "gram per normal cubic metre (g/Nm³)", + "value": "congNm3" + } + ], + "text": "concentration" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -337,7 +2525,1090 @@ "kind": "grafana-polystat-panel", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-polystat-panel", + "originalOptions": { + "animationModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "d3DivId": "d3_svg_5", + "decimals": 2, + "displayModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "fontSizes": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70 + ], + "fontTypes": [ + "Open Sans", + "Arial", + "Avant Garde", + "Bookman", + "Consolas", + "Courier", + "Courier New", + "Futura", + "Garamond", + "Helvetica", + "Palatino", + "Times", + "Times New Roman", + "Verdana" + ], + "format": "none", + "notcolors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "operatorName": "avg", + "operatorOptions": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Count", + "value": "count" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Delta", + "value": "delta" + }, + { + "text": "Difference", + "value": "diff" + }, + { + "text": "First", + "value": "first" + }, + { + "text": "Log Min", + "value": "logmin" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Min", + "value": "min" + }, + { + "text": "Name", + "value": "name" + }, + { + "text": "Time of Last Point", + "value": "last_time" + }, + { + "text": "Time Step", + "value": "time_step" + }, + { + "text": "Total", + "value": "total" + } + ], + "polystat": { + "animationSpeed": 2500, + "columnAutoSize": true, + "columns": "", + "defaultClickThrough": "", + "defaultClickThroughSanitize": true, + "displayLimit": 100, + "fontAutoScale": true, + "fontSize": 12, + "globalDisplayMode": "all", + "globalOperatorName": "avg", + "gradientEnabled": true, + "hexagonSortByDirection": "asc", + "hexagonSortByField": "name", + "maxMetrics": 0, + "polygonBorderColor": "black", + "polygonBorderSize": 2, + "radius": "", + "radiusAutoSize": true, + "rowAutoSize": true, + "rows": "", + "shape": "hexagon_pointed_top", + "tooltipDisplayMode": "all", + "tooltipDisplayTextTriggeredEmpty": "OK", + "tooltipFontSize": 12, + "tooltipFontType": "Open Sans", + "tooltipPrimarySortDirection": "desc", + "tooltipPrimarySortField": "thresholdLevel", + "tooltipSecondarySortDirection": "desc", + "tooltipSecondarySortField": "value", + "tooltipTimestampEnabled": true + }, + "savedComposites": [ + { + "animateMode": "all", + "clickThrough": "", + "compositeName": "comp", + "enabled": true, + "hideMembers": true, + "members": [ + { + "seriesName": "A-series" + }, + { + "seriesName": "B-series" + } + ], + "sanitizeURLEnabled": true, + "sanitizedURL": "", + "showName": true, + "showValue": true, + "thresholdLevel": 0 + } + ], + "savedOverrides": [], + "shapes": [ + { + "text": "Hexagon Pointed Top", + "value": "hexagon_pointed_top" + }, + { + "text": "Hexagon Flat Top", + "value": "hexagon_flat_top" + }, + { + "text": "Circle", + "value": "circle" + }, + { + "text": "Cross", + "value": "cross" + }, + { + "text": "Diamond", + "value": "diamond" + }, + { + "text": "Square", + "value": "square" + }, + { + "text": "Star", + "value": "star" + }, + { + "text": "Triangle", + "value": "triangle" + }, + { + "text": "Wye", + "value": "wye" + } + ], + "sortDirections": [ + { + "text": "Ascending", + "value": "asc" + }, + { + "text": "Descending", + "value": "desc" + } + ], + "sortFields": [ + { + "text": "Name", + "value": "name" + }, + { + "text": "Threshold Level", + "value": "thresholdLevel" + }, + { + "text": "Value", + "value": "value" + } + ], + "svgContainer": {}, + "thresholdStates": [ + { + "text": "ok", + "value": 0 + }, + { + "text": "warning", + "value": 1 + }, + { + "text": "critical", + "value": 2 + }, + { + "text": "custom", + "value": 3 + } + ], + "unitFormats": [ + { + "submenu": [ + { + "text": "none", + "value": "none" + }, + { + "text": "short", + "value": "short" + }, + { + "text": "percent (0-100)", + "value": "percent" + }, + { + "text": "percent (0.0-1.0)", + "value": "percentunit" + }, + { + "text": "Humidity (%H)", + "value": "humidity" + }, + { + "text": "decibel", + "value": "dB" + }, + { + "text": "hexadecimal (0x)", + "value": "hex0x" + }, + { + "text": "hexadecimal", + "value": "hex" + }, + { + "text": "scientific notation", + "value": "sci" + }, + { + "text": "locale format", + "value": "locale" + } + ], + "text": "none" + }, + { + "submenu": [ + { + "text": "Dollars ($)", + "value": "currencyUSD" + }, + { + "text": "Pounds (£)", + "value": "currencyGBP" + }, + { + "text": "Euro (€)", + "value": "currencyEUR" + }, + { + "text": "Yen (¥)", + "value": "currencyJPY" + }, + { + "text": "Rubles (₽)", + "value": "currencyRUB" + }, + { + "text": "Hryvnias (₴)", + "value": "currencyUAH" + }, + { + "text": "Real (R$)", + "value": "currencyBRL" + }, + { + "text": "Danish Krone (kr)", + "value": "currencyDKK" + }, + { + "text": "Icelandic Króna (kr)", + "value": "currencyISK" + }, + { + "text": "Norwegian Krone (kr)", + "value": "currencyNOK" + }, + { + "text": "Swedish Krona (kr)", + "value": "currencySEK" + }, + { + "text": "Czech koruna (czk)", + "value": "currencyCZK" + }, + { + "text": "Swiss franc (CHF)", + "value": "currencyCHF" + }, + { + "text": "Polish Złoty (PLN)", + "value": "currencyPLN" + }, + { + "text": "Bitcoin (฿)", + "value": "currencyBTC" + }, + { + "text": "Vietnamese Dong (VND)", + "value": "currencyVND" + }, + { + "text": "Malaysian Ringgit (RM)", + "value": "currencyMYR" + }, + { + "text": "Bulgarian Lev (BGN)", + "value": "currencyBGN" + } + ], + "text": "currency" + }, + { + "submenu": [ + { + "text": "Hertz (1/s)", + "value": "hertz" + }, + { + "text": "nanoseconds (ns)", + "value": "ns" + }, + { + "text": "microseconds (µs)", + "value": "µs" + }, + { + "text": "milliseconds (ms)", + "value": "ms" + }, + { + "text": "seconds (s)", + "value": "s" + }, + { + "text": "minutes (m)", + "value": "m" + }, + { + "text": "hours (h)", + "value": "h" + }, + { + "text": "days (d)", + "value": "d" + }, + { + "text": "duration (ms)", + "value": "dtdurationms" + }, + { + "text": "duration (s)", + "value": "dtdurations" + }, + { + "text": "duration (hh:mm:ss)", + "value": "dthms" + }, + { + "text": "Timeticks (s/100)", + "value": "timeticks" + } + ], + "text": "time" + }, + { + "submenu": [ + { + "text": "YYYY-MM-DD HH:mm:ss", + "value": "dateTimeAsIso" + }, + { + "text": "DD/MM/YYYY h:mm:ss a", + "value": "dateTimeAsUS" + }, + { + "text": "From Now", + "value": "dateTimeFromNow" + } + ], + "text": "date \u0026 time" + }, + { + "submenu": [ + { + "text": "bits", + "value": "bits" + }, + { + "text": "bytes", + "value": "bytes" + }, + { + "text": "kibibytes", + "value": "kbytes" + }, + { + "text": "mebibytes", + "value": "mbytes" + }, + { + "text": "gibibytes", + "value": "gbytes" + } + ], + "text": "data (IEC)" + }, + { + "submenu": [ + { + "text": "bits", + "value": "decbits" + }, + { + "text": "bytes", + "value": "decbytes" + }, + { + "text": "kilobytes", + "value": "deckbytes" + }, + { + "text": "megabytes", + "value": "decmbytes" + }, + { + "text": "gigabytes", + "value": "decgbytes" + } + ], + "text": "data (Metric)" + }, + { + "submenu": [ + { + "text": "packets/sec", + "value": "pps" + }, + { + "text": "bits/sec", + "value": "bps" + }, + { + "text": "bytes/sec", + "value": "Bps" + }, + { + "text": "kilobits/sec", + "value": "Kbits" + }, + { + "text": "kilobytes/sec", + "value": "KBs" + }, + { + "text": "megabits/sec", + "value": "Mbits" + }, + { + "text": "megabytes/sec", + "value": "MBs" + }, + { + "text": "gigabytes/sec", + "value": "GBs" + }, + { + "text": "gigabits/sec", + "value": "Gbits" + } + ], + "text": "data rate" + }, + { + "submenu": [ + { + "text": "hashes/sec", + "value": "Hs" + }, + { + "text": "kilohashes/sec", + "value": "KHs" + }, + { + "text": "megahashes/sec", + "value": "MHs" + }, + { + "text": "gigahashes/sec", + "value": "GHs" + }, + { + "text": "terahashes/sec", + "value": "THs" + }, + { + "text": "petahashes/sec", + "value": "PHs" + }, + { + "text": "exahashes/sec", + "value": "EHs" + } + ], + "text": "hash rate" + }, + { + "submenu": [ + { + "text": "ops/sec (ops)", + "value": "ops" + }, + { + "text": "requests/sec (rps)", + "value": "reqps" + }, + { + "text": "reads/sec (rps)", + "value": "rps" + }, + { + "text": "writes/sec (wps)", + "value": "wps" + }, + { + "text": "I/O ops/sec (iops)", + "value": "iops" + }, + { + "text": "ops/min (opm)", + "value": "opm" + }, + { + "text": "reads/min (rpm)", + "value": "rpm" + }, + { + "text": "writes/min (wpm)", + "value": "wpm" + } + ], + "text": "throughput" + }, + { + "submenu": [ + { + "text": "millimetre (mm)", + "value": "lengthmm" + }, + { + "text": "meter (m)", + "value": "lengthm" + }, + { + "text": "inch (in)", + "value": "lengthin" + }, + { + "text": "feet (ft)", + "value": "lengthft" + }, + { + "text": "kilometer (km)", + "value": "lengthkm" + }, + { + "text": "mile (mi)", + "value": "lengthmi" + } + ], + "text": "length" + }, + { + "submenu": [ + { + "text": "Square Meters (m²)", + "value": "areaM2" + }, + { + "text": "Square Feet (ft²)", + "value": "areaF2" + }, + { + "text": "Square Miles (mi²)", + "value": "areaMI2" + } + ], + "text": "area" + }, + { + "submenu": [ + { + "text": "milligram (mg)", + "value": "massmg" + }, + { + "text": "gram (g)", + "value": "massg" + }, + { + "text": "pound (lb)", + "value": "masslb" + }, + { + "text": "kilogram (kg)", + "value": "masskg" + }, + { + "text": "metric ton (t)", + "value": "masst" + } + ], + "text": "mass" + }, + { + "submenu": [ + { + "text": "metres/second (m/s)", + "value": "velocityms" + }, + { + "text": "kilometers/hour (km/h)", + "value": "velocitykmh" + }, + { + "text": "miles/hour (mph)", + "value": "velocitymph" + }, + { + "text": "knot (kn)", + "value": "velocityknot" + } + ], + "text": "velocity" + }, + { + "submenu": [ + { + "text": "millilitre (mL)", + "value": "mlitre" + }, + { + "text": "litre (L)", + "value": "litre" + }, + { + "text": "cubic metre", + "value": "m3" + }, + { + "text": "Normal cubic metre", + "value": "Nm3" + }, + { + "text": "cubic decimetre", + "value": "dm3" + }, + { + "text": "gallons", + "value": "gallons" + } + ], + "text": "volume" + }, + { + "submenu": [ + { + "text": "Watt (W)", + "value": "watt" + }, + { + "text": "Kilowatt (kW)", + "value": "kwatt" + }, + { + "text": "Milliwatt (mW)", + "value": "mwatt" + }, + { + "text": "Watt per square metre (W/m²)", + "value": "Wm2" + }, + { + "text": "Volt-ampere (VA)", + "value": "voltamp" + }, + { + "text": "Kilovolt-ampere (kVA)", + "value": "kvoltamp" + }, + { + "text": "Volt-ampere reactive (var)", + "value": "voltampreact" + }, + { + "text": "Kilovolt-ampere reactive (kvar)", + "value": "kvoltampreact" + }, + { + "text": "Watt-hour (Wh)", + "value": "watth" + }, + { + "text": "Kilowatt-hour (kWh)", + "value": "kwatth" + }, + { + "text": "Kilowatt-min (kWm)", + "value": "kwattm" + }, + { + "text": "Joule (J)", + "value": "joule" + }, + { + "text": "Electron volt (eV)", + "value": "ev" + }, + { + "text": "Ampere (A)", + "value": "amp" + }, + { + "text": "Kiloampere (kA)", + "value": "kamp" + }, + { + "text": "Milliampere (mA)", + "value": "mamp" + }, + { + "text": "Volt (V)", + "value": "volt" + }, + { + "text": "Kilovolt (kV)", + "value": "kvolt" + }, + { + "text": "Millivolt (mV)", + "value": "mvolt" + }, + { + "text": "Decibel-milliwatt (dBm)", + "value": "dBm" + }, + { + "text": "Ohm (Ω)", + "value": "ohm" + }, + { + "text": "Lumens (Lm)", + "value": "lumens" + } + ], + "text": "energy" + }, + { + "submenu": [ + { + "text": "Celsius (°C)", + "value": "celsius" + }, + { + "text": "Fahrenheit (°F)", + "value": "fahrenheit" + }, + { + "text": "Kelvin (K)", + "value": "kelvin" + } + ], + "text": "temperature" + }, + { + "submenu": [ + { + "text": "Millibars", + "value": "pressurembar" + }, + { + "text": "Bars", + "value": "pressurebar" + }, + { + "text": "Kilobars", + "value": "pressurekbar" + }, + { + "text": "Hectopascals", + "value": "pressurehpa" + }, + { + "text": "Kilopascals", + "value": "pressurekpa" + }, + { + "text": "Inches of mercury", + "value": "pressurehg" + }, + { + "text": "PSI", + "value": "pressurepsi" + } + ], + "text": "pressure" + }, + { + "submenu": [ + { + "text": "Newton-meters (Nm)", + "value": "forceNm" + }, + { + "text": "Kilonewton-meters (kNm)", + "value": "forcekNm" + }, + { + "text": "Newtons (N)", + "value": "forceN" + }, + { + "text": "Kilonewtons (kN)", + "value": "forcekN" + } + ], + "text": "force" + }, + { + "submenu": [ + { + "text": "Gallons/min (gpm)", + "value": "flowgpm" + }, + { + "text": "Cubic meters/sec (cms)", + "value": "flowcms" + }, + { + "text": "Cubic feet/sec (cfs)", + "value": "flowcfs" + }, + { + "text": "Cubic feet/min (cfm)", + "value": "flowcfm" + }, + { + "text": "Litre/hour", + "value": "litreh" + }, + { + "text": "Litre/min (l/min)", + "value": "flowlpm" + }, + { + "text": "milliLitre/min (mL/min)", + "value": "flowmlpm" + } + ], + "text": "flow" + }, + { + "submenu": [ + { + "text": "Degrees (°)", + "value": "degree" + }, + { + "text": "Radians", + "value": "radian" + }, + { + "text": "Gradian", + "value": "grad" + } + ], + "text": "angle" + }, + { + "submenu": [ + { + "text": "Meters/sec²", + "value": "accMS2" + }, + { + "text": "Feet/sec²", + "value": "accFS2" + }, + { + "text": "G unit", + "value": "accG" + } + ], + "text": "acceleration" + }, + { + "submenu": [ + { + "text": "Becquerel (Bq)", + "value": "radbq" + }, + { + "text": "curie (Ci)", + "value": "radci" + }, + { + "text": "Gray (Gy)", + "value": "radgy" + }, + { + "text": "rad", + "value": "radrad" + }, + { + "text": "Sievert (Sv)", + "value": "radsv" + }, + { + "text": "rem", + "value": "radrem" + }, + { + "text": "Exposure (C/kg)", + "value": "radexpckg" + }, + { + "text": "roentgen (R)", + "value": "radr" + }, + { + "text": "Sievert/hour (Sv/h)", + "value": "radsvh" + } + ], + "text": "radiation" + }, + { + "submenu": [ + { + "text": "parts-per-million (ppm)", + "value": "ppm" + }, + { + "text": "parts-per-billion (ppb)", + "value": "conppb" + }, + { + "text": "nanogram per cubic metre (ng/m³)", + "value": "conngm3" + }, + { + "text": "nanogram per normal cubic metre (ng/Nm³)", + "value": "conngNm3" + }, + { + "text": "microgram per cubic metre (μg/m³)", + "value": "conμgm3" + }, + { + "text": "microgram per normal cubic metre (μg/Nm³)", + "value": "conμgNm3" + }, + { + "text": "milligram per cubic metre (mg/m³)", + "value": "conmgm3" + }, + { + "text": "milligram per normal cubic metre (mg/Nm³)", + "value": "conmgNm3" + }, + { + "text": "gram per cubic metre (g/m³)", + "value": "congm3" + }, + { + "text": "gram per normal cubic metre (g/Nm³)", + "value": "congNm3" + } + ], + "text": "concentration" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -424,5 +3695,10 @@ "title": "Panel Tests - Polystat", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2beta1.json index 46644077d0c..5916250ffd5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-polystat/v0alpha1.polystat_test.v42.v2beta1.json @@ -130,7 +130,1073 @@ "group": "grafana-polystat-panel", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-polystat-panel", + "originalOptions": { + "animationModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "d3DivId": "d3_svg_2", + "decimals": 2, + "displayModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "fontSizes": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70 + ], + "fontTypes": [ + "Open Sans", + "Arial", + "Avant Garde", + "Bookman", + "Consolas", + "Courier", + "Courier New", + "Futura", + "Garamond", + "Helvetica", + "Palatino", + "Times", + "Times New Roman", + "Verdana" + ], + "format": "none", + "notcolors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "operatorName": "avg", + "operatorOptions": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Count", + "value": "count" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Delta", + "value": "delta" + }, + { + "text": "Difference", + "value": "diff" + }, + { + "text": "First", + "value": "first" + }, + { + "text": "Log Min", + "value": "logmin" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Min", + "value": "min" + }, + { + "text": "Name", + "value": "name" + }, + { + "text": "Time of Last Point", + "value": "last_time" + }, + { + "text": "Time Step", + "value": "time_step" + }, + { + "text": "Total", + "value": "total" + } + ], + "polystat": { + "animationSpeed": 2500, + "columnAutoSize": true, + "columns": 1, + "defaultClickThrough": "", + "defaultClickThroughSanitize": true, + "displayLimit": 100, + "fontAutoScale": true, + "fontSize": 12, + "globalDisplayMode": "all", + "globalOperatorName": "avg", + "gradientEnabled": true, + "hexagonSortByDirection": "asc", + "hexagonSortByField": "name", + "maxMetrics": 0, + "polygonBorderColor": "black", + "polygonBorderSize": 2, + "radius": "", + "radiusAutoSize": true, + "rowAutoSize": true, + "rows": 1, + "shape": "hexagon_pointed_top", + "tooltipDisplayMode": "all", + "tooltipDisplayTextTriggeredEmpty": "OK", + "tooltipFontSize": 12, + "tooltipFontType": "Open Sans", + "tooltipPrimarySortDirection": "desc", + "tooltipPrimarySortField": "thresholdLevel", + "tooltipSecondarySortDirection": "desc", + "tooltipSecondarySortField": "value", + "tooltipTimestampEnabled": true + }, + "savedComposites": [], + "savedOverrides": [], + "shapes": [ + { + "text": "Hexagon Pointed Top", + "value": "hexagon_pointed_top" + }, + { + "text": "Hexagon Flat Top", + "value": "hexagon_flat_top" + }, + { + "text": "Circle", + "value": "circle" + }, + { + "text": "Cross", + "value": "cross" + }, + { + "text": "Diamond", + "value": "diamond" + }, + { + "text": "Square", + "value": "square" + }, + { + "text": "Star", + "value": "star" + }, + { + "text": "Triangle", + "value": "triangle" + }, + { + "text": "Wye", + "value": "wye" + } + ], + "sortDirections": [ + { + "text": "Ascending", + "value": "asc" + }, + { + "text": "Descending", + "value": "desc" + } + ], + "sortFields": [ + { + "text": "Name", + "value": "name" + }, + { + "text": "Threshold Level", + "value": "thresholdLevel" + }, + { + "text": "Value", + "value": "value" + } + ], + "svgContainer": {}, + "thresholdStates": [ + { + "text": "ok", + "value": 0 + }, + { + "text": "warning", + "value": 1 + }, + { + "text": "critical", + "value": 2 + }, + { + "text": "custom", + "value": 3 + } + ], + "unitFormats": [ + { + "submenu": [ + { + "text": "none", + "value": "none" + }, + { + "text": "short", + "value": "short" + }, + { + "text": "percent (0-100)", + "value": "percent" + }, + { + "text": "percent (0.0-1.0)", + "value": "percentunit" + }, + { + "text": "Humidity (%H)", + "value": "humidity" + }, + { + "text": "decibel", + "value": "dB" + }, + { + "text": "hexadecimal (0x)", + "value": "hex0x" + }, + { + "text": "hexadecimal", + "value": "hex" + }, + { + "text": "scientific notation", + "value": "sci" + }, + { + "text": "locale format", + "value": "locale" + } + ], + "text": "none" + }, + { + "submenu": [ + { + "text": "Dollars ($)", + "value": "currencyUSD" + }, + { + "text": "Pounds (£)", + "value": "currencyGBP" + }, + { + "text": "Euro (€)", + "value": "currencyEUR" + }, + { + "text": "Yen (¥)", + "value": "currencyJPY" + }, + { + "text": "Rubles (₽)", + "value": "currencyRUB" + }, + { + "text": "Hryvnias (₴)", + "value": "currencyUAH" + }, + { + "text": "Real (R$)", + "value": "currencyBRL" + }, + { + "text": "Danish Krone (kr)", + "value": "currencyDKK" + }, + { + "text": "Icelandic Króna (kr)", + "value": "currencyISK" + }, + { + "text": "Norwegian Krone (kr)", + "value": "currencyNOK" + }, + { + "text": "Swedish Krona (kr)", + "value": "currencySEK" + }, + { + "text": "Czech koruna (czk)", + "value": "currencyCZK" + }, + { + "text": "Swiss franc (CHF)", + "value": "currencyCHF" + }, + { + "text": "Polish Złoty (PLN)", + "value": "currencyPLN" + }, + { + "text": "Bitcoin (฿)", + "value": "currencyBTC" + }, + { + "text": "Vietnamese Dong (VND)", + "value": "currencyVND" + }, + { + "text": "Malaysian Ringgit (RM)", + "value": "currencyMYR" + }, + { + "text": "Bulgarian Lev (BGN)", + "value": "currencyBGN" + } + ], + "text": "currency" + }, + { + "submenu": [ + { + "text": "Hertz (1/s)", + "value": "hertz" + }, + { + "text": "nanoseconds (ns)", + "value": "ns" + }, + { + "text": "microseconds (µs)", + "value": "µs" + }, + { + "text": "milliseconds (ms)", + "value": "ms" + }, + { + "text": "seconds (s)", + "value": "s" + }, + { + "text": "minutes (m)", + "value": "m" + }, + { + "text": "hours (h)", + "value": "h" + }, + { + "text": "days (d)", + "value": "d" + }, + { + "text": "duration (ms)", + "value": "dtdurationms" + }, + { + "text": "duration (s)", + "value": "dtdurations" + }, + { + "text": "duration (hh:mm:ss)", + "value": "dthms" + }, + { + "text": "Timeticks (s/100)", + "value": "timeticks" + } + ], + "text": "time" + }, + { + "submenu": [ + { + "text": "YYYY-MM-DD HH:mm:ss", + "value": "dateTimeAsIso" + }, + { + "text": "DD/MM/YYYY h:mm:ss a", + "value": "dateTimeAsUS" + }, + { + "text": "From Now", + "value": "dateTimeFromNow" + } + ], + "text": "date \u0026 time" + }, + { + "submenu": [ + { + "text": "bits", + "value": "bits" + }, + { + "text": "bytes", + "value": "bytes" + }, + { + "text": "kibibytes", + "value": "kbytes" + }, + { + "text": "mebibytes", + "value": "mbytes" + }, + { + "text": "gibibytes", + "value": "gbytes" + } + ], + "text": "data (IEC)" + }, + { + "submenu": [ + { + "text": "bits", + "value": "decbits" + }, + { + "text": "bytes", + "value": "decbytes" + }, + { + "text": "kilobytes", + "value": "deckbytes" + }, + { + "text": "megabytes", + "value": "decmbytes" + }, + { + "text": "gigabytes", + "value": "decgbytes" + } + ], + "text": "data (Metric)" + }, + { + "submenu": [ + { + "text": "packets/sec", + "value": "pps" + }, + { + "text": "bits/sec", + "value": "bps" + }, + { + "text": "bytes/sec", + "value": "Bps" + }, + { + "text": "kilobits/sec", + "value": "Kbits" + }, + { + "text": "kilobytes/sec", + "value": "KBs" + }, + { + "text": "megabits/sec", + "value": "Mbits" + }, + { + "text": "megabytes/sec", + "value": "MBs" + }, + { + "text": "gigabytes/sec", + "value": "GBs" + }, + { + "text": "gigabits/sec", + "value": "Gbits" + } + ], + "text": "data rate" + }, + { + "submenu": [ + { + "text": "hashes/sec", + "value": "Hs" + }, + { + "text": "kilohashes/sec", + "value": "KHs" + }, + { + "text": "megahashes/sec", + "value": "MHs" + }, + { + "text": "gigahashes/sec", + "value": "GHs" + }, + { + "text": "terahashes/sec", + "value": "THs" + }, + { + "text": "petahashes/sec", + "value": "PHs" + }, + { + "text": "exahashes/sec", + "value": "EHs" + } + ], + "text": "hash rate" + }, + { + "submenu": [ + { + "text": "ops/sec (ops)", + "value": "ops" + }, + { + "text": "requests/sec (rps)", + "value": "reqps" + }, + { + "text": "reads/sec (rps)", + "value": "rps" + }, + { + "text": "writes/sec (wps)", + "value": "wps" + }, + { + "text": "I/O ops/sec (iops)", + "value": "iops" + }, + { + "text": "ops/min (opm)", + "value": "opm" + }, + { + "text": "requests/min (rpm)", + "value": "reqpm" + }, + { + "text": "reads/min (rpm)", + "value": "rpm" + }, + { + "text": "writes/min (wpm)", + "value": "wpm" + } + ], + "text": "throughput" + }, + { + "submenu": [ + { + "text": "millimetre (mm)", + "value": "lengthmm" + }, + { + "text": "meter (m)", + "value": "lengthm" + }, + { + "text": "inch (in)", + "value": "lengthin" + }, + { + "text": "feet (ft)", + "value": "lengthft" + }, + { + "text": "kilometer (km)", + "value": "lengthkm" + }, + { + "text": "mile (mi)", + "value": "lengthmi" + } + ], + "text": "length" + }, + { + "submenu": [ + { + "text": "Square Meters (m²)", + "value": "areaM2" + }, + { + "text": "Square Feet (ft²)", + "value": "areaF2" + }, + { + "text": "Square Miles (mi²)", + "value": "areaMI2" + } + ], + "text": "area" + }, + { + "submenu": [ + { + "text": "milligram (mg)", + "value": "massmg" + }, + { + "text": "gram (g)", + "value": "massg" + }, + { + "text": "pound (lb)", + "value": "masslb" + }, + { + "text": "kilogram (kg)", + "value": "masskg" + }, + { + "text": "metric ton (t)", + "value": "masst" + } + ], + "text": "mass" + }, + { + "submenu": [ + { + "text": "metres/second (m/s)", + "value": "velocityms" + }, + { + "text": "kilometers/hour (km/h)", + "value": "velocitykmh" + }, + { + "text": "miles/hour (mph)", + "value": "velocitymph" + }, + { + "text": "knot (kn)", + "value": "velocityknot" + } + ], + "text": "velocity" + }, + { + "submenu": [ + { + "text": "millilitre (mL)", + "value": "mlitre" + }, + { + "text": "litre (L)", + "value": "litre" + }, + { + "text": "cubic metre", + "value": "m3" + }, + { + "text": "Normal cubic metre", + "value": "Nm3" + }, + { + "text": "cubic decimetre", + "value": "dm3" + }, + { + "text": "gallons", + "value": "gallons" + } + ], + "text": "volume" + }, + { + "submenu": [ + { + "text": "Watt (W)", + "value": "watt" + }, + { + "text": "Kilowatt (kW)", + "value": "kwatt" + }, + { + "text": "Milliwatt (mW)", + "value": "mwatt" + }, + { + "text": "Watt per square metre (W/m²)", + "value": "Wm2" + }, + { + "text": "Volt-ampere (VA)", + "value": "voltamp" + }, + { + "text": "Kilovolt-ampere (kVA)", + "value": "kvoltamp" + }, + { + "text": "Volt-ampere reactive (var)", + "value": "voltampreact" + }, + { + "text": "Kilovolt-ampere reactive (kvar)", + "value": "kvoltampreact" + }, + { + "text": "Watt-hour (Wh)", + "value": "watth" + }, + { + "text": "Kilowatt-hour (kWh)", + "value": "kwatth" + }, + { + "text": "Kilowatt-min (kWm)", + "value": "kwattm" + }, + { + "text": "Joule (J)", + "value": "joule" + }, + { + "text": "Electron volt (eV)", + "value": "ev" + }, + { + "text": "Ampere (A)", + "value": "amp" + }, + { + "text": "Kiloampere (kA)", + "value": "kamp" + }, + { + "text": "Milliampere (mA)", + "value": "mamp" + }, + { + "text": "Volt (V)", + "value": "volt" + }, + { + "text": "Kilovolt (kV)", + "value": "kvolt" + }, + { + "text": "Millivolt (mV)", + "value": "mvolt" + }, + { + "text": "Decibel-milliwatt (dBm)", + "value": "dBm" + }, + { + "text": "Ohm (Ω)", + "value": "ohm" + }, + { + "text": "Lumens (Lm)", + "value": "lumens" + } + ], + "text": "energy" + }, + { + "submenu": [ + { + "text": "Celsius (°C)", + "value": "celsius" + }, + { + "text": "Fahrenheit (°F)", + "value": "fahrenheit" + }, + { + "text": "Kelvin (K)", + "value": "kelvin" + } + ], + "text": "temperature" + }, + { + "submenu": [ + { + "text": "Millibars", + "value": "pressurembar" + }, + { + "text": "Bars", + "value": "pressurebar" + }, + { + "text": "Kilobars", + "value": "pressurekbar" + }, + { + "text": "Hectopascals", + "value": "pressurehpa" + }, + { + "text": "Kilopascals", + "value": "pressurekpa" + }, + { + "text": "Inches of mercury", + "value": "pressurehg" + }, + { + "text": "PSI", + "value": "pressurepsi" + } + ], + "text": "pressure" + }, + { + "submenu": [ + { + "text": "Newton-meters (Nm)", + "value": "forceNm" + }, + { + "text": "Kilonewton-meters (kNm)", + "value": "forcekNm" + }, + { + "text": "Newtons (N)", + "value": "forceN" + }, + { + "text": "Kilonewtons (kN)", + "value": "forcekN" + } + ], + "text": "force" + }, + { + "submenu": [ + { + "text": "Gallons/min (gpm)", + "value": "flowgpm" + }, + { + "text": "Cubic meters/sec (cms)", + "value": "flowcms" + }, + { + "text": "Cubic feet/sec (cfs)", + "value": "flowcfs" + }, + { + "text": "Cubic feet/min (cfm)", + "value": "flowcfm" + }, + { + "text": "Litre/hour", + "value": "litreh" + }, + { + "text": "Litre/min (l/min)", + "value": "flowlpm" + }, + { + "text": "milliLitre/min (mL/min)", + "value": "flowmlpm" + } + ], + "text": "flow" + }, + { + "submenu": [ + { + "text": "Degrees (°)", + "value": "degree" + }, + { + "text": "Radians", + "value": "radian" + }, + { + "text": "Gradian", + "value": "grad" + } + ], + "text": "angle" + }, + { + "submenu": [ + { + "text": "Meters/sec²", + "value": "accMS2" + }, + { + "text": "Feet/sec²", + "value": "accFS2" + }, + { + "text": "G unit", + "value": "accG" + } + ], + "text": "acceleration" + }, + { + "submenu": [ + { + "text": "Becquerel (Bq)", + "value": "radbq" + }, + { + "text": "curie (Ci)", + "value": "radci" + }, + { + "text": "Gray (Gy)", + "value": "radgy" + }, + { + "text": "rad", + "value": "radrad" + }, + { + "text": "Sievert (Sv)", + "value": "radsv" + }, + { + "text": "rem", + "value": "radrem" + }, + { + "text": "Exposure (C/kg)", + "value": "radexpckg" + }, + { + "text": "roentgen (R)", + "value": "radr" + }, + { + "text": "Sievert/hour (Sv/h)", + "value": "radsvh" + } + ], + "text": "radiation" + }, + { + "submenu": [ + { + "text": "parts-per-million (ppm)", + "value": "ppm" + }, + { + "text": "parts-per-billion (ppb)", + "value": "conppb" + }, + { + "text": "nanogram per cubic metre (ng/m³)", + "value": "conngm3" + }, + { + "text": "nanogram per normal cubic metre (ng/Nm³)", + "value": "conngNm3" + }, + { + "text": "microgram per cubic metre (μg/m³)", + "value": "conμgm3" + }, + { + "text": "microgram per normal cubic metre (μg/Nm³)", + "value": "conμgNm3" + }, + { + "text": "milligram per cubic metre (mg/m³)", + "value": "conmgm3" + }, + { + "text": "milligram per normal cubic metre (mg/Nm³)", + "value": "conmgNm3" + }, + { + "text": "gram per cubic metre (g/m³)", + "value": "congm3" + }, + { + "text": "gram per normal cubic metre (g/Nm³)", + "value": "congNm3" + } + ], + "text": "concentration" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -250,7 +1316,1129 @@ "group": "grafana-polystat-panel", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-polystat-panel", + "originalOptions": { + "animationModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "d3DivId": "d3_svg_4", + "decimals": 2, + "displayModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "fontSizes": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70 + ], + "fontTypes": [ + "Open Sans", + "Arial", + "Avant Garde", + "Bookman", + "Consolas", + "Courier", + "Courier New", + "Futura", + "Garamond", + "Helvetica", + "Palatino", + "Times", + "Times New Roman", + "Verdana" + ], + "format": "none", + "notcolors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "operatorName": "avg", + "operatorOptions": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Count", + "value": "count" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Delta", + "value": "delta" + }, + { + "text": "Difference", + "value": "diff" + }, + { + "text": "First", + "value": "first" + }, + { + "text": "Log Min", + "value": "logmin" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Min", + "value": "min" + }, + { + "text": "Name", + "value": "name" + }, + { + "text": "Time of Last Point", + "value": "last_time" + }, + { + "text": "Time Step", + "value": "time_step" + }, + { + "text": "Total", + "value": "total" + } + ], + "polystat": { + "animationSpeed": 2500, + "columnAutoSize": true, + "columns": "", + "defaultClickThrough": "", + "defaultClickThroughSanitize": true, + "displayLimit": 100, + "fontAutoScale": true, + "fontSize": 12, + "globalDisplayMode": "all", + "globalOperatorName": "avg", + "gradientEnabled": true, + "hexagonSortByDirection": "asc", + "hexagonSortByField": "name", + "maxMetrics": 0, + "polygonBorderColor": "black", + "polygonBorderSize": 2, + "radius": "", + "radiusAutoSize": true, + "rowAutoSize": true, + "rows": "", + "shape": "hexagon_pointed_top", + "tooltipDisplayMode": "all", + "tooltipDisplayTextTriggeredEmpty": "OK", + "tooltipFontSize": 12, + "tooltipFontType": "Open Sans", + "tooltipPrimarySortDirection": "desc", + "tooltipPrimarySortField": "thresholdLevel", + "tooltipSecondarySortDirection": "desc", + "tooltipSecondarySortField": "value", + "tooltipTimestampEnabled": true + }, + "savedComposites": [], + "savedOverrides": [], + "shapes": [ + { + "text": "Hexagon Pointed Top", + "value": "hexagon_pointed_top" + }, + { + "text": "Hexagon Flat Top", + "value": "hexagon_flat_top" + }, + { + "text": "Circle", + "value": "circle" + }, + { + "text": "Cross", + "value": "cross" + }, + { + "text": "Diamond", + "value": "diamond" + }, + { + "text": "Square", + "value": "square" + }, + { + "text": "Star", + "value": "star" + }, + { + "text": "Triangle", + "value": "triangle" + }, + { + "text": "Wye", + "value": "wye" + } + ], + "sortDirections": [ + { + "text": "Ascending", + "value": "asc" + }, + { + "text": "Descending", + "value": "desc" + } + ], + "sortFields": [ + { + "text": "Name", + "value": "name" + }, + { + "text": "Threshold Level", + "value": "thresholdLevel" + }, + { + "text": "Value", + "value": "value" + } + ], + "svgContainer": {}, + "thresholdStates": [ + { + "text": "ok", + "value": 0 + }, + { + "text": "warning", + "value": 1 + }, + { + "text": "critical", + "value": 2 + }, + { + "text": "custom", + "value": 3 + } + ], + "unitFormats": [ + { + "submenu": [ + { + "text": "none", + "value": "none" + }, + { + "text": "short", + "value": "short" + }, + { + "text": "percent (0-100)", + "value": "percent" + }, + { + "text": "percent (0.0-1.0)", + "value": "percentunit" + }, + { + "text": "Humidity (%H)", + "value": "humidity" + }, + { + "text": "decibel", + "value": "dB" + }, + { + "text": "hexadecimal (0x)", + "value": "hex0x" + }, + { + "text": "hexadecimal", + "value": "hex" + }, + { + "text": "scientific notation", + "value": "sci" + }, + { + "text": "locale format", + "value": "locale" + } + ], + "text": "none" + }, + { + "submenu": [ + { + "text": "Dollars ($)", + "value": "currencyUSD" + }, + { + "text": "Pounds (£)", + "value": "currencyGBP" + }, + { + "text": "Euro (€)", + "value": "currencyEUR" + }, + { + "text": "Yen (¥)", + "value": "currencyJPY" + }, + { + "text": "Rubles (₽)", + "value": "currencyRUB" + }, + { + "text": "Hryvnias (₴)", + "value": "currencyUAH" + }, + { + "text": "Real (R$)", + "value": "currencyBRL" + }, + { + "text": "Danish Krone (kr)", + "value": "currencyDKK" + }, + { + "text": "Icelandic Króna (kr)", + "value": "currencyISK" + }, + { + "text": "Norwegian Krone (kr)", + "value": "currencyNOK" + }, + { + "text": "Swedish Krona (kr)", + "value": "currencySEK" + }, + { + "text": "Czech koruna (czk)", + "value": "currencyCZK" + }, + { + "text": "Swiss franc (CHF)", + "value": "currencyCHF" + }, + { + "text": "Polish Złoty (PLN)", + "value": "currencyPLN" + }, + { + "text": "Bitcoin (฿)", + "value": "currencyBTC" + }, + { + "text": "Milli Bitcoin (mBTC)", + "value": "currencymBTC" + }, + { + "text": "Micro Bitcoin (μBTC)", + "value": "currencyμBTC" + }, + { + "text": "Vietnamese Dong (VND)", + "value": "currencyVND" + }, + { + "text": "Turkish Lira (₺)", + "value": "currencyTRY" + }, + { + "text": "Malaysian Ringgit (RM)", + "value": "currencyMYR" + }, + { + "text": "CFP franc (XPF)", + "value": "currencyXPF" + }, + { + "text": "Bulgarian Lev (BGN)", + "value": "currencyBGN" + } + ], + "text": "currency" + }, + { + "submenu": [ + { + "text": "Hertz (1/s)", + "value": "hertz" + }, + { + "text": "nanoseconds (ns)", + "value": "ns" + }, + { + "text": "microseconds (µs)", + "value": "µs" + }, + { + "text": "milliseconds (ms)", + "value": "ms" + }, + { + "text": "seconds (s)", + "value": "s" + }, + { + "text": "minutes (m)", + "value": "m" + }, + { + "text": "hours (h)", + "value": "h" + }, + { + "text": "days (d)", + "value": "d" + }, + { + "text": "duration (ms)", + "value": "dtdurationms" + }, + { + "text": "duration (s)", + "value": "dtdurations" + }, + { + "text": "duration (hh:mm:ss)", + "value": "dthms" + }, + { + "text": "Timeticks (s/100)", + "value": "timeticks" + } + ], + "text": "time" + }, + { + "submenu": [ + { + "text": "YYYY-MM-DD HH:mm:ss", + "value": "dateTimeAsIso" + }, + { + "text": "DD/MM/YYYY h:mm:ss a", + "value": "dateTimeAsUS" + }, + { + "text": "From Now", + "value": "dateTimeFromNow" + } + ], + "text": "date \u0026 time" + }, + { + "submenu": [ + { + "text": "bits", + "value": "bits" + }, + { + "text": "bytes", + "value": "bytes" + }, + { + "text": "kibibytes", + "value": "kbytes" + }, + { + "text": "mebibytes", + "value": "mbytes" + }, + { + "text": "gibibytes", + "value": "gbytes" + } + ], + "text": "data (IEC)" + }, + { + "submenu": [ + { + "text": "bits", + "value": "decbits" + }, + { + "text": "bytes", + "value": "decbytes" + }, + { + "text": "kilobytes", + "value": "deckbytes" + }, + { + "text": "megabytes", + "value": "decmbytes" + }, + { + "text": "gigabytes", + "value": "decgbytes" + } + ], + "text": "data (Metric)" + }, + { + "submenu": [ + { + "text": "packets/sec", + "value": "pps" + }, + { + "text": "bits/sec", + "value": "bps" + }, + { + "text": "bytes/sec", + "value": "Bps" + }, + { + "text": "kilobits/sec", + "value": "Kbits" + }, + { + "text": "kilobytes/sec", + "value": "KBs" + }, + { + "text": "megabits/sec", + "value": "Mbits" + }, + { + "text": "megabytes/sec", + "value": "MBs" + }, + { + "text": "gigabytes/sec", + "value": "GBs" + }, + { + "text": "gigabits/sec", + "value": "Gbits" + } + ], + "text": "data rate" + }, + { + "submenu": [ + { + "text": "hashes/sec", + "value": "Hs" + }, + { + "text": "kilohashes/sec", + "value": "KHs" + }, + { + "text": "megahashes/sec", + "value": "MHs" + }, + { + "text": "gigahashes/sec", + "value": "GHs" + }, + { + "text": "terahashes/sec", + "value": "THs" + }, + { + "text": "petahashes/sec", + "value": "PHs" + }, + { + "text": "exahashes/sec", + "value": "EHs" + } + ], + "text": "hash rate" + }, + { + "submenu": [ + { + "text": "counts/sec (cps)", + "value": "cps" + }, + { + "text": "ops/sec (ops)", + "value": "ops" + }, + { + "text": "requests/sec (rps)", + "value": "reqps" + }, + { + "text": "reads/sec (rps)", + "value": "rps" + }, + { + "text": "writes/sec (wps)", + "value": "wps" + }, + { + "text": "I/O ops/sec (iops)", + "value": "iops" + }, + { + "text": "events/sec (eps)", + "value": "eps" + }, + { + "text": "messages/sec (mps)", + "value": "mps" + }, + { + "text": "records/sec (rps)", + "value": "recps" + }, + { + "text": "rows/sec (rps)", + "value": "rowsps" + }, + { + "text": "counts/min (cpm)", + "value": "cpm" + }, + { + "text": "ops/min (opm)", + "value": "opm" + }, + { + "text": "requests/min (rpm)", + "value": "reqpm" + }, + { + "text": "reads/min (rpm)", + "value": "rpm" + }, + { + "text": "writes/min (wpm)", + "value": "wpm" + }, + { + "text": "events/min (epm)", + "value": "epm" + }, + { + "text": "messages/min (mpm)", + "value": "mpm" + }, + { + "text": "records/min (rpm)", + "value": "recpm" + }, + { + "text": "rows/min (rpm)", + "value": "rowspm" + } + ], + "text": "throughput" + }, + { + "submenu": [ + { + "text": "millimetre (mm)", + "value": "lengthmm" + }, + { + "text": "meter (m)", + "value": "lengthm" + }, + { + "text": "inch (in)", + "value": "lengthin" + }, + { + "text": "feet (ft)", + "value": "lengthft" + }, + { + "text": "kilometer (km)", + "value": "lengthkm" + }, + { + "text": "mile (mi)", + "value": "lengthmi" + } + ], + "text": "length" + }, + { + "submenu": [ + { + "text": "Square Meters (m²)", + "value": "areaM2" + }, + { + "text": "Square Feet (ft²)", + "value": "areaF2" + }, + { + "text": "Square Miles (mi²)", + "value": "areaMI2" + } + ], + "text": "area" + }, + { + "submenu": [ + { + "text": "milligram (mg)", + "value": "massmg" + }, + { + "text": "gram (g)", + "value": "massg" + }, + { + "text": "pound (lb)", + "value": "masslb" + }, + { + "text": "kilogram (kg)", + "value": "masskg" + }, + { + "text": "metric ton (t)", + "value": "masst" + } + ], + "text": "mass" + }, + { + "submenu": [ + { + "text": "metres/second (m/s)", + "value": "velocityms" + }, + { + "text": "kilometers/hour (km/h)", + "value": "velocitykmh" + }, + { + "text": "miles/hour (mph)", + "value": "velocitymph" + }, + { + "text": "knot (kn)", + "value": "velocityknot" + } + ], + "text": "velocity" + }, + { + "submenu": [ + { + "text": "millilitre (mL)", + "value": "mlitre" + }, + { + "text": "litre (L)", + "value": "litre" + }, + { + "text": "cubic metre", + "value": "m3" + }, + { + "text": "Normal cubic metre", + "value": "Nm3" + }, + { + "text": "cubic decimetre", + "value": "dm3" + }, + { + "text": "gallons", + "value": "gallons" + } + ], + "text": "volume" + }, + { + "submenu": [ + { + "text": "Watt (W)", + "value": "watt" + }, + { + "text": "Kilowatt (kW)", + "value": "kwatt" + }, + { + "text": "Milliwatt (mW)", + "value": "mwatt" + }, + { + "text": "Watt per square metre (W/m²)", + "value": "Wm2" + }, + { + "text": "Volt-Ampere (VA)", + "value": "voltamp" + }, + { + "text": "Kilovolt-Ampere (kVA)", + "value": "kvoltamp" + }, + { + "text": "Volt-Ampere reactive (VAr)", + "value": "voltampreact" + }, + { + "text": "Kilovolt-Ampere reactive (kVAr)", + "value": "kvoltampreact" + }, + { + "text": "Watt-hour (Wh)", + "value": "watth" + }, + { + "text": "Kilowatt-hour (kWh)", + "value": "kwatth" + }, + { + "text": "Kilowatt-min (kWm)", + "value": "kwattm" + }, + { + "text": "Joule (J)", + "value": "joule" + }, + { + "text": "Electron volt (eV)", + "value": "ev" + }, + { + "text": "Ampere (A)", + "value": "amp" + }, + { + "text": "Kiloampere (kA)", + "value": "kamp" + }, + { + "text": "Milliampere (mA)", + "value": "mamp" + }, + { + "text": "Volt (V)", + "value": "volt" + }, + { + "text": "Kilovolt (kV)", + "value": "kvolt" + }, + { + "text": "Millivolt (mV)", + "value": "mvolt" + }, + { + "text": "Decibel-milliwatt (dBm)", + "value": "dBm" + }, + { + "text": "Ohm (Ω)", + "value": "ohm" + }, + { + "text": "Lumens (Lm)", + "value": "lumens" + } + ], + "text": "energy" + }, + { + "submenu": [ + { + "text": "Celsius (°C)", + "value": "celsius" + }, + { + "text": "Fahrenheit (°F)", + "value": "fahrenheit" + }, + { + "text": "Kelvin (K)", + "value": "kelvin" + } + ], + "text": "temperature" + }, + { + "submenu": [ + { + "text": "Millibars", + "value": "pressurembar" + }, + { + "text": "Bars", + "value": "pressurebar" + }, + { + "text": "Kilobars", + "value": "pressurekbar" + }, + { + "text": "Hectopascals", + "value": "pressurehpa" + }, + { + "text": "Kilopascals", + "value": "pressurekpa" + }, + { + "text": "Inches of mercury", + "value": "pressurehg" + }, + { + "text": "PSI", + "value": "pressurepsi" + } + ], + "text": "pressure" + }, + { + "submenu": [ + { + "text": "Newton-meters (Nm)", + "value": "forceNm" + }, + { + "text": "Kilonewton-meters (kNm)", + "value": "forcekNm" + }, + { + "text": "Newtons (N)", + "value": "forceN" + }, + { + "text": "Kilonewtons (kN)", + "value": "forcekN" + } + ], + "text": "force" + }, + { + "submenu": [ + { + "text": "Gallons/min (gpm)", + "value": "flowgpm" + }, + { + "text": "Cubic meters/sec (cms)", + "value": "flowcms" + }, + { + "text": "Cubic feet/sec (cfs)", + "value": "flowcfs" + }, + { + "text": "Cubic feet/min (cfm)", + "value": "flowcfm" + }, + { + "text": "Litre/hour", + "value": "litreh" + }, + { + "text": "Litre/min (l/min)", + "value": "flowlpm" + }, + { + "text": "milliLitre/min (mL/min)", + "value": "flowmlpm" + } + ], + "text": "flow" + }, + { + "submenu": [ + { + "text": "Degrees (°)", + "value": "degree" + }, + { + "text": "Radians", + "value": "radian" + }, + { + "text": "Gradian", + "value": "grad" + } + ], + "text": "angle" + }, + { + "submenu": [ + { + "text": "Meters/sec²", + "value": "accMS2" + }, + { + "text": "Feet/sec²", + "value": "accFS2" + }, + { + "text": "G unit", + "value": "accG" + } + ], + "text": "acceleration" + }, + { + "submenu": [ + { + "text": "Becquerel (Bq)", + "value": "radbq" + }, + { + "text": "curie (Ci)", + "value": "radci" + }, + { + "text": "Gray (Gy)", + "value": "radgy" + }, + { + "text": "rad", + "value": "radrad" + }, + { + "text": "Sievert (Sv)", + "value": "radsv" + }, + { + "text": "rem", + "value": "radrem" + }, + { + "text": "Exposure (C/kg)", + "value": "radexpckg" + }, + { + "text": "roentgen (R)", + "value": "radr" + }, + { + "text": "Sievert/hour (Sv/h)", + "value": "radsvh" + } + ], + "text": "radiation" + }, + { + "submenu": [ + { + "text": "parts-per-million (ppm)", + "value": "ppm" + }, + { + "text": "parts-per-billion (ppb)", + "value": "conppb" + }, + { + "text": "nanogram per cubic metre (ng/m³)", + "value": "conngm3" + }, + { + "text": "nanogram per normal cubic metre (ng/Nm³)", + "value": "conngNm3" + }, + { + "text": "microgram per cubic metre (μg/m³)", + "value": "conμgm3" + }, + { + "text": "microgram per normal cubic metre (μg/Nm³)", + "value": "conμgNm3" + }, + { + "text": "milligram per cubic metre (mg/m³)", + "value": "conmgm3" + }, + { + "text": "milligram per normal cubic metre (mg/Nm³)", + "value": "conmgNm3" + }, + { + "text": "gram per cubic metre (g/m³)", + "value": "congm3" + }, + { + "text": "gram per normal cubic metre (g/Nm³)", + "value": "congNm3" + } + ], + "text": "concentration" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -370,7 +2558,1090 @@ "group": "grafana-polystat-panel", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-polystat-panel", + "originalOptions": { + "animationModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "d3DivId": "d3_svg_5", + "decimals": 2, + "displayModes": [ + { + "text": "Show All", + "value": "all" + }, + { + "text": "Show Triggered", + "value": "triggered" + } + ], + "fontSizes": [ + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70 + ], + "fontTypes": [ + "Open Sans", + "Arial", + "Avant Garde", + "Bookman", + "Consolas", + "Courier", + "Courier New", + "Futura", + "Garamond", + "Helvetica", + "Palatino", + "Times", + "Times New Roman", + "Verdana" + ], + "format": "none", + "notcolors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "operatorName": "avg", + "operatorOptions": [ + { + "text": "Average", + "value": "avg" + }, + { + "text": "Count", + "value": "count" + }, + { + "text": "Current", + "value": "current" + }, + { + "text": "Delta", + "value": "delta" + }, + { + "text": "Difference", + "value": "diff" + }, + { + "text": "First", + "value": "first" + }, + { + "text": "Log Min", + "value": "logmin" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Min", + "value": "min" + }, + { + "text": "Name", + "value": "name" + }, + { + "text": "Time of Last Point", + "value": "last_time" + }, + { + "text": "Time Step", + "value": "time_step" + }, + { + "text": "Total", + "value": "total" + } + ], + "polystat": { + "animationSpeed": 2500, + "columnAutoSize": true, + "columns": "", + "defaultClickThrough": "", + "defaultClickThroughSanitize": true, + "displayLimit": 100, + "fontAutoScale": true, + "fontSize": 12, + "globalDisplayMode": "all", + "globalOperatorName": "avg", + "gradientEnabled": true, + "hexagonSortByDirection": "asc", + "hexagonSortByField": "name", + "maxMetrics": 0, + "polygonBorderColor": "black", + "polygonBorderSize": 2, + "radius": "", + "radiusAutoSize": true, + "rowAutoSize": true, + "rows": "", + "shape": "hexagon_pointed_top", + "tooltipDisplayMode": "all", + "tooltipDisplayTextTriggeredEmpty": "OK", + "tooltipFontSize": 12, + "tooltipFontType": "Open Sans", + "tooltipPrimarySortDirection": "desc", + "tooltipPrimarySortField": "thresholdLevel", + "tooltipSecondarySortDirection": "desc", + "tooltipSecondarySortField": "value", + "tooltipTimestampEnabled": true + }, + "savedComposites": [ + { + "animateMode": "all", + "clickThrough": "", + "compositeName": "comp", + "enabled": true, + "hideMembers": true, + "members": [ + { + "seriesName": "A-series" + }, + { + "seriesName": "B-series" + } + ], + "sanitizeURLEnabled": true, + "sanitizedURL": "", + "showName": true, + "showValue": true, + "thresholdLevel": 0 + } + ], + "savedOverrides": [], + "shapes": [ + { + "text": "Hexagon Pointed Top", + "value": "hexagon_pointed_top" + }, + { + "text": "Hexagon Flat Top", + "value": "hexagon_flat_top" + }, + { + "text": "Circle", + "value": "circle" + }, + { + "text": "Cross", + "value": "cross" + }, + { + "text": "Diamond", + "value": "diamond" + }, + { + "text": "Square", + "value": "square" + }, + { + "text": "Star", + "value": "star" + }, + { + "text": "Triangle", + "value": "triangle" + }, + { + "text": "Wye", + "value": "wye" + } + ], + "sortDirections": [ + { + "text": "Ascending", + "value": "asc" + }, + { + "text": "Descending", + "value": "desc" + } + ], + "sortFields": [ + { + "text": "Name", + "value": "name" + }, + { + "text": "Threshold Level", + "value": "thresholdLevel" + }, + { + "text": "Value", + "value": "value" + } + ], + "svgContainer": {}, + "thresholdStates": [ + { + "text": "ok", + "value": 0 + }, + { + "text": "warning", + "value": 1 + }, + { + "text": "critical", + "value": 2 + }, + { + "text": "custom", + "value": 3 + } + ], + "unitFormats": [ + { + "submenu": [ + { + "text": "none", + "value": "none" + }, + { + "text": "short", + "value": "short" + }, + { + "text": "percent (0-100)", + "value": "percent" + }, + { + "text": "percent (0.0-1.0)", + "value": "percentunit" + }, + { + "text": "Humidity (%H)", + "value": "humidity" + }, + { + "text": "decibel", + "value": "dB" + }, + { + "text": "hexadecimal (0x)", + "value": "hex0x" + }, + { + "text": "hexadecimal", + "value": "hex" + }, + { + "text": "scientific notation", + "value": "sci" + }, + { + "text": "locale format", + "value": "locale" + } + ], + "text": "none" + }, + { + "submenu": [ + { + "text": "Dollars ($)", + "value": "currencyUSD" + }, + { + "text": "Pounds (£)", + "value": "currencyGBP" + }, + { + "text": "Euro (€)", + "value": "currencyEUR" + }, + { + "text": "Yen (¥)", + "value": "currencyJPY" + }, + { + "text": "Rubles (₽)", + "value": "currencyRUB" + }, + { + "text": "Hryvnias (₴)", + "value": "currencyUAH" + }, + { + "text": "Real (R$)", + "value": "currencyBRL" + }, + { + "text": "Danish Krone (kr)", + "value": "currencyDKK" + }, + { + "text": "Icelandic Króna (kr)", + "value": "currencyISK" + }, + { + "text": "Norwegian Krone (kr)", + "value": "currencyNOK" + }, + { + "text": "Swedish Krona (kr)", + "value": "currencySEK" + }, + { + "text": "Czech koruna (czk)", + "value": "currencyCZK" + }, + { + "text": "Swiss franc (CHF)", + "value": "currencyCHF" + }, + { + "text": "Polish Złoty (PLN)", + "value": "currencyPLN" + }, + { + "text": "Bitcoin (฿)", + "value": "currencyBTC" + }, + { + "text": "Vietnamese Dong (VND)", + "value": "currencyVND" + }, + { + "text": "Malaysian Ringgit (RM)", + "value": "currencyMYR" + }, + { + "text": "Bulgarian Lev (BGN)", + "value": "currencyBGN" + } + ], + "text": "currency" + }, + { + "submenu": [ + { + "text": "Hertz (1/s)", + "value": "hertz" + }, + { + "text": "nanoseconds (ns)", + "value": "ns" + }, + { + "text": "microseconds (µs)", + "value": "µs" + }, + { + "text": "milliseconds (ms)", + "value": "ms" + }, + { + "text": "seconds (s)", + "value": "s" + }, + { + "text": "minutes (m)", + "value": "m" + }, + { + "text": "hours (h)", + "value": "h" + }, + { + "text": "days (d)", + "value": "d" + }, + { + "text": "duration (ms)", + "value": "dtdurationms" + }, + { + "text": "duration (s)", + "value": "dtdurations" + }, + { + "text": "duration (hh:mm:ss)", + "value": "dthms" + }, + { + "text": "Timeticks (s/100)", + "value": "timeticks" + } + ], + "text": "time" + }, + { + "submenu": [ + { + "text": "YYYY-MM-DD HH:mm:ss", + "value": "dateTimeAsIso" + }, + { + "text": "DD/MM/YYYY h:mm:ss a", + "value": "dateTimeAsUS" + }, + { + "text": "From Now", + "value": "dateTimeFromNow" + } + ], + "text": "date \u0026 time" + }, + { + "submenu": [ + { + "text": "bits", + "value": "bits" + }, + { + "text": "bytes", + "value": "bytes" + }, + { + "text": "kibibytes", + "value": "kbytes" + }, + { + "text": "mebibytes", + "value": "mbytes" + }, + { + "text": "gibibytes", + "value": "gbytes" + } + ], + "text": "data (IEC)" + }, + { + "submenu": [ + { + "text": "bits", + "value": "decbits" + }, + { + "text": "bytes", + "value": "decbytes" + }, + { + "text": "kilobytes", + "value": "deckbytes" + }, + { + "text": "megabytes", + "value": "decmbytes" + }, + { + "text": "gigabytes", + "value": "decgbytes" + } + ], + "text": "data (Metric)" + }, + { + "submenu": [ + { + "text": "packets/sec", + "value": "pps" + }, + { + "text": "bits/sec", + "value": "bps" + }, + { + "text": "bytes/sec", + "value": "Bps" + }, + { + "text": "kilobits/sec", + "value": "Kbits" + }, + { + "text": "kilobytes/sec", + "value": "KBs" + }, + { + "text": "megabits/sec", + "value": "Mbits" + }, + { + "text": "megabytes/sec", + "value": "MBs" + }, + { + "text": "gigabytes/sec", + "value": "GBs" + }, + { + "text": "gigabits/sec", + "value": "Gbits" + } + ], + "text": "data rate" + }, + { + "submenu": [ + { + "text": "hashes/sec", + "value": "Hs" + }, + { + "text": "kilohashes/sec", + "value": "KHs" + }, + { + "text": "megahashes/sec", + "value": "MHs" + }, + { + "text": "gigahashes/sec", + "value": "GHs" + }, + { + "text": "terahashes/sec", + "value": "THs" + }, + { + "text": "petahashes/sec", + "value": "PHs" + }, + { + "text": "exahashes/sec", + "value": "EHs" + } + ], + "text": "hash rate" + }, + { + "submenu": [ + { + "text": "ops/sec (ops)", + "value": "ops" + }, + { + "text": "requests/sec (rps)", + "value": "reqps" + }, + { + "text": "reads/sec (rps)", + "value": "rps" + }, + { + "text": "writes/sec (wps)", + "value": "wps" + }, + { + "text": "I/O ops/sec (iops)", + "value": "iops" + }, + { + "text": "ops/min (opm)", + "value": "opm" + }, + { + "text": "reads/min (rpm)", + "value": "rpm" + }, + { + "text": "writes/min (wpm)", + "value": "wpm" + } + ], + "text": "throughput" + }, + { + "submenu": [ + { + "text": "millimetre (mm)", + "value": "lengthmm" + }, + { + "text": "meter (m)", + "value": "lengthm" + }, + { + "text": "inch (in)", + "value": "lengthin" + }, + { + "text": "feet (ft)", + "value": "lengthft" + }, + { + "text": "kilometer (km)", + "value": "lengthkm" + }, + { + "text": "mile (mi)", + "value": "lengthmi" + } + ], + "text": "length" + }, + { + "submenu": [ + { + "text": "Square Meters (m²)", + "value": "areaM2" + }, + { + "text": "Square Feet (ft²)", + "value": "areaF2" + }, + { + "text": "Square Miles (mi²)", + "value": "areaMI2" + } + ], + "text": "area" + }, + { + "submenu": [ + { + "text": "milligram (mg)", + "value": "massmg" + }, + { + "text": "gram (g)", + "value": "massg" + }, + { + "text": "pound (lb)", + "value": "masslb" + }, + { + "text": "kilogram (kg)", + "value": "masskg" + }, + { + "text": "metric ton (t)", + "value": "masst" + } + ], + "text": "mass" + }, + { + "submenu": [ + { + "text": "metres/second (m/s)", + "value": "velocityms" + }, + { + "text": "kilometers/hour (km/h)", + "value": "velocitykmh" + }, + { + "text": "miles/hour (mph)", + "value": "velocitymph" + }, + { + "text": "knot (kn)", + "value": "velocityknot" + } + ], + "text": "velocity" + }, + { + "submenu": [ + { + "text": "millilitre (mL)", + "value": "mlitre" + }, + { + "text": "litre (L)", + "value": "litre" + }, + { + "text": "cubic metre", + "value": "m3" + }, + { + "text": "Normal cubic metre", + "value": "Nm3" + }, + { + "text": "cubic decimetre", + "value": "dm3" + }, + { + "text": "gallons", + "value": "gallons" + } + ], + "text": "volume" + }, + { + "submenu": [ + { + "text": "Watt (W)", + "value": "watt" + }, + { + "text": "Kilowatt (kW)", + "value": "kwatt" + }, + { + "text": "Milliwatt (mW)", + "value": "mwatt" + }, + { + "text": "Watt per square metre (W/m²)", + "value": "Wm2" + }, + { + "text": "Volt-ampere (VA)", + "value": "voltamp" + }, + { + "text": "Kilovolt-ampere (kVA)", + "value": "kvoltamp" + }, + { + "text": "Volt-ampere reactive (var)", + "value": "voltampreact" + }, + { + "text": "Kilovolt-ampere reactive (kvar)", + "value": "kvoltampreact" + }, + { + "text": "Watt-hour (Wh)", + "value": "watth" + }, + { + "text": "Kilowatt-hour (kWh)", + "value": "kwatth" + }, + { + "text": "Kilowatt-min (kWm)", + "value": "kwattm" + }, + { + "text": "Joule (J)", + "value": "joule" + }, + { + "text": "Electron volt (eV)", + "value": "ev" + }, + { + "text": "Ampere (A)", + "value": "amp" + }, + { + "text": "Kiloampere (kA)", + "value": "kamp" + }, + { + "text": "Milliampere (mA)", + "value": "mamp" + }, + { + "text": "Volt (V)", + "value": "volt" + }, + { + "text": "Kilovolt (kV)", + "value": "kvolt" + }, + { + "text": "Millivolt (mV)", + "value": "mvolt" + }, + { + "text": "Decibel-milliwatt (dBm)", + "value": "dBm" + }, + { + "text": "Ohm (Ω)", + "value": "ohm" + }, + { + "text": "Lumens (Lm)", + "value": "lumens" + } + ], + "text": "energy" + }, + { + "submenu": [ + { + "text": "Celsius (°C)", + "value": "celsius" + }, + { + "text": "Fahrenheit (°F)", + "value": "fahrenheit" + }, + { + "text": "Kelvin (K)", + "value": "kelvin" + } + ], + "text": "temperature" + }, + { + "submenu": [ + { + "text": "Millibars", + "value": "pressurembar" + }, + { + "text": "Bars", + "value": "pressurebar" + }, + { + "text": "Kilobars", + "value": "pressurekbar" + }, + { + "text": "Hectopascals", + "value": "pressurehpa" + }, + { + "text": "Kilopascals", + "value": "pressurekpa" + }, + { + "text": "Inches of mercury", + "value": "pressurehg" + }, + { + "text": "PSI", + "value": "pressurepsi" + } + ], + "text": "pressure" + }, + { + "submenu": [ + { + "text": "Newton-meters (Nm)", + "value": "forceNm" + }, + { + "text": "Kilonewton-meters (kNm)", + "value": "forcekNm" + }, + { + "text": "Newtons (N)", + "value": "forceN" + }, + { + "text": "Kilonewtons (kN)", + "value": "forcekN" + } + ], + "text": "force" + }, + { + "submenu": [ + { + "text": "Gallons/min (gpm)", + "value": "flowgpm" + }, + { + "text": "Cubic meters/sec (cms)", + "value": "flowcms" + }, + { + "text": "Cubic feet/sec (cfs)", + "value": "flowcfs" + }, + { + "text": "Cubic feet/min (cfm)", + "value": "flowcfm" + }, + { + "text": "Litre/hour", + "value": "litreh" + }, + { + "text": "Litre/min (l/min)", + "value": "flowlpm" + }, + { + "text": "milliLitre/min (mL/min)", + "value": "flowmlpm" + } + ], + "text": "flow" + }, + { + "submenu": [ + { + "text": "Degrees (°)", + "value": "degree" + }, + { + "text": "Radians", + "value": "radian" + }, + { + "text": "Gradian", + "value": "grad" + } + ], + "text": "angle" + }, + { + "submenu": [ + { + "text": "Meters/sec²", + "value": "accMS2" + }, + { + "text": "Feet/sec²", + "value": "accFS2" + }, + { + "text": "G unit", + "value": "accG" + } + ], + "text": "acceleration" + }, + { + "submenu": [ + { + "text": "Becquerel (Bq)", + "value": "radbq" + }, + { + "text": "curie (Ci)", + "value": "radci" + }, + { + "text": "Gray (Gy)", + "value": "radgy" + }, + { + "text": "rad", + "value": "radrad" + }, + { + "text": "Sievert (Sv)", + "value": "radsv" + }, + { + "text": "rem", + "value": "radrem" + }, + { + "text": "Exposure (C/kg)", + "value": "radexpckg" + }, + { + "text": "roentgen (R)", + "value": "radr" + }, + { + "text": "Sievert/hour (Sv/h)", + "value": "radsvh" + } + ], + "text": "radiation" + }, + { + "submenu": [ + { + "text": "parts-per-million (ppm)", + "value": "ppm" + }, + { + "text": "parts-per-billion (ppb)", + "value": "conppb" + }, + { + "text": "nanogram per cubic metre (ng/m³)", + "value": "conngm3" + }, + { + "text": "nanogram per normal cubic metre (ng/Nm³)", + "value": "conngNm3" + }, + { + "text": "microgram per cubic metre (μg/m³)", + "value": "conμgm3" + }, + { + "text": "microgram per normal cubic metre (μg/Nm³)", + "value": "conμgNm3" + }, + { + "text": "milligram per cubic metre (mg/m³)", + "value": "conmgm3" + }, + { + "text": "milligram per normal cubic metre (mg/Nm³)", + "value": "conmgNm3" + }, + { + "text": "gram per cubic metre (g/m³)", + "value": "congm3" + }, + { + "text": "gram per normal cubic metre (g/Nm³)", + "value": "congNm3" + } + ], + "text": "concentration" + } + ] + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -457,5 +3728,10 @@ "title": "Panel Tests - Polystat", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2alpha1.json index acb35da6bb8..2074ff4fa12 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2alpha1.json @@ -2768,5 +2768,10 @@ "title": "Panel Tests - Stat", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2beta1.json index fb9f810cfaa..98b11ebadb3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-stat/v0alpha1.panel-stat-tests.v42.v2beta1.json @@ -2883,5 +2883,10 @@ "title": "Panel Tests - Stat", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2alpha1.json index 44db8ddd292..d90c8dc52cd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2alpha1.json @@ -1498,5 +1498,10 @@ "title": "StatusHistory - Thresholds \u0026 Mappings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2beta1.json index 513bc4d476c..7aaa0fff33a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-status-history/v0alpha1.status-history-thresholds-mappings.v42.v2beta1.json @@ -1537,5 +1537,10 @@ "title": "StatusHistory - Thresholds \u0026 Mappings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2alpha1.json index 2697100f4cd..540f0d9e54d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2alpha1.json @@ -1893,5 +1893,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2beta1.json index ec3f1d1ed5c..6c9aa023163 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_footer.v42.v2beta1.json @@ -1939,5 +1939,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2alpha1.json index d2ec399b434..bccce10d162 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2alpha1.json @@ -2192,5 +2192,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2beta1.json index a2ea184c554..5e186ef1443 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_kitchen_sink.v42.v2beta1.json @@ -2227,5 +2227,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2alpha1.json index 2bbd6a111bc..4863b46eeb3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2alpha1.json @@ -178,5 +178,10 @@ "title": "Panel Tests - Table - Markdown", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2beta1.json index 4a1f3a61afd..1964dd78543 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_markdown.v42.v2beta1.json @@ -181,5 +181,10 @@ "title": "Panel Tests - Table - Markdown", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2alpha1.json index e637af09f52..cb0c2bbc16d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2alpha1.json @@ -3000,5 +3000,10 @@ "title": "Panel Tests - Table - Pagination", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2beta1.json index bc15692c4cb..d79b6c9e68b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_pagination.v42.v2beta1.json @@ -3018,5 +3018,10 @@ "title": "Panel Tests - Table - Pagination", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2alpha1.json index 78012512792..e5e260fd150 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2alpha1.json @@ -824,5 +824,10 @@ "title": "Panel Tests - Table - Sparklines", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2beta1.json index 352bab0c09b..ac15a298939 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_sparkline_cell.v42.v2beta1.json @@ -846,5 +846,10 @@ "title": "Panel Tests - Table - Sparklines", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2alpha1.json index 9d3a3f84f61..c706000d557 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2alpha1.json @@ -80,7 +80,85 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -142,7 +220,86 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "pageSize": 10, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_rows" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -204,7 +361,99 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [ + { + "text": "Avg", + "value": "avg" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Current", + "value": "current" + } + ], + "fontSize": "100%", + "pageSize": 10, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_aggregations" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -251,7 +500,65 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "row", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "/Color/", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -313,7 +620,92 @@ "kind": "table", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "pageSize": 20, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.5)", + "rgba(237, 129, 40, 0.5)", + "rgba(50, 172, 45, 0.5)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": true, + "linkTooltip": "", + "linkUrl": "http://www.grafana.com", + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.5)", + "rgba(237, 129, 40, 0.5)", + "rgba(50, 172, 45, 0.5)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkUrl": "http://www.grafana.com", + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -426,5 +818,10 @@ "title": "Panel Tests - Table", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2beta1.json index 2b97a31452a..3ddb128c20e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests.v42.v2beta1.json @@ -87,7 +87,85 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -154,7 +232,86 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "pageSize": 10, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_rows" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -221,7 +378,99 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [ + { + "text": "Avg", + "value": "avg" + }, + { + "text": "Max", + "value": "max" + }, + { + "text": "Current", + "value": "current" + } + ], + "fontSize": "100%", + "pageSize": 10, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_aggregations" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -271,7 +520,65 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "row", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "mappingType": 1, + "pattern": "/Color/", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -338,7 +645,92 @@ "group": "table", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "pageSize": 20, + "scroll": true, + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "auto", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.5)", + "rgba(237, 129, 40, 0.5)", + "rgba(50, 172, 45, 0.5)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTargetBlank": true, + "linkTooltip": "", + "linkUrl": "http://www.grafana.com", + "mappingType": 1, + "pattern": "ColorCell", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "currencyUSD" + }, + { + "alias": "", + "align": "auto", + "colorMode": "value", + "colors": [ + "rgba(245, 54, 54, 0.5)", + "rgba(237, 129, 40, 0.5)", + "rgba(50, 172, 45, 0.5)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkUrl": "http://www.grafana.com", + "mappingType": 1, + "pattern": "ColorValue", + "thresholds": [ + "5", + "10" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "align": "auto", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "timeseries_to_columns" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -451,5 +843,10 @@ "title": "Panel Tests - Table", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2alpha1.json index 25624e5c6d1..4e35b317cd9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2alpha1.json @@ -1252,5 +1252,10 @@ "title": "Panel Tests - React Table", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2beta1.json index b8d5f8acae3..8911415d0fc 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_tests_new.v42.v2beta1.json @@ -1280,5 +1280,10 @@ "title": "Panel Tests - React Table", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2alpha1.json index b8e6725ca5a..1b6348c35d5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2alpha1.json @@ -2507,5 +2507,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2beta1.json index 4a7ea3bcf33..a77140c5beb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-table/v0alpha1.table_v12_2_migrations.v42.v2beta1.json @@ -2550,5 +2550,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2alpha1.json index e0299a0be0f..3ac4d6901f4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2alpha1.json @@ -431,5 +431,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2beta1.json index a93a6c13852..6e8243f3131 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-text/v0alpha1.text-options.v42.v2beta1.json @@ -450,5 +450,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2alpha1.json index 15877291ee7..cb30e79d196 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2alpha1.json @@ -356,5 +356,10 @@ "title": "Panel Tests - StateTimeline - multiple frames with endTime", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2beta1.json index 1d857be3ea5..34c3f244b54 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-endtime.v42.v2beta1.json @@ -365,5 +365,10 @@ "title": "Panel Tests - StateTimeline - multiple frames with endTime", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2alpha1.json index 7a2c436af82..13303a094ec 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2alpha1.json @@ -263,5 +263,10 @@ "title": "Panel Tests - StateTimeline - multiple frames with nulls", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2beta1.json index 4b14dcf2810..7d8376e9106 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-align-nulls-retain.v42.v2beta1.json @@ -267,5 +267,10 @@ "title": "Panel Tests - StateTimeline - multiple frames with nulls", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2alpha1.json index 522ec817718..82500d25a30 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2alpha1.json @@ -670,5 +670,10 @@ "title": "Timeline Demo", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2beta1.json index 8e01aece508..89c7db392ea 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-demo.v42.v2beta1.json @@ -699,5 +699,10 @@ "title": "Timeline Demo", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2alpha1.json index 7c8170cbcf8..9b4b2edfb80 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2alpha1.json @@ -548,5 +548,10 @@ "title": "Timeline Modes", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2beta1.json index f5f4d53dba6..35d2643cc81 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-modes.v42.v2beta1.json @@ -566,5 +566,10 @@ "title": "Timeline Modes", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2alpha1.json index ff492690353..8dff3c34ccf 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2alpha1.json @@ -1498,5 +1498,10 @@ "title": "StateTimeline - Thresholds \u0026 Mappings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2beta1.json index 6dcd28290db..3baa3d21130 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeline/v0alpha1.timeline-thresholds-mappings.v42.v2beta1.json @@ -1537,5 +1537,10 @@ "title": "StateTimeline - Thresholds \u0026 Mappings", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2alpha1.json index f18b9741878..6f3390c4d11 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2alpha1.json @@ -790,5 +790,10 @@ "title": "Panel Tests - TimeSeries - bars high density (stroke + fill)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2beta1.json index 797c81e39f0..00de0e2092b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-bars-high-density.v42.v2beta1.json @@ -805,5 +805,10 @@ "title": "Panel Tests - TimeSeries - bars high density (stroke + fill)", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2alpha1.json index d51c3443680..2d0e6b76950 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2alpha1.json @@ -1374,5 +1374,10 @@ "title": "Panel Tests - Graph NG - By value color schemes", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2beta1.json index cc2f62859f9..a3f729f9c5f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-by-value-color-schemes.v42.v2beta1.json @@ -1403,5 +1403,10 @@ "title": "Panel Tests - Graph NG - By value color schemes", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2alpha1.json index 766832b0cb7..ac083165532 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2alpha1.json @@ -1067,5 +1067,10 @@ "title": "Panel Tests - Timeseries - Supported input formats", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2beta1.json index da1784c2b52..25ed3a1cf9b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-formats.v42.v2beta1.json @@ -1076,5 +1076,10 @@ "title": "Panel Tests - Timeseries - Supported input formats", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2alpha1.json index 7ad3c386000..5b43876c65f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2alpha1.json @@ -799,5 +799,10 @@ "title": "Panel Tests - Graph NG - Gradient Area Fills", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2beta1.json index 4def562428b..ca96f9d5720 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-gradient-area.v42.v2beta1.json @@ -813,5 +813,10 @@ "title": "Panel Tests - Graph NG - Gradient Area Fills", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2alpha1.json index 0f5a4c7473e..74cba148009 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2alpha1.json @@ -1215,5 +1215,10 @@ "title": "Panel Tests - GraphNG - Hue Gradients", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2beta1.json index e7e54fd938b..7e64bc79ef3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-hue-gradients.v42.v2beta1.json @@ -1235,5 +1235,10 @@ "title": "Panel Tests - GraphNG - Hue Gradients", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2alpha1.json index 9bf92a90234..718a96c265c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2alpha1.json @@ -4362,5 +4362,10 @@ "title": "Panel Tests - Graph NG - Discrete panels", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2beta1.json index 3678e2c1bb8..187a377bdf1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-nulls.v42.v2beta1.json @@ -4462,5 +4462,10 @@ "title": "Panel Tests - Graph NG - Discrete panels", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2alpha1.json index 7bfea9b01ad..f1bff310950 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2alpha1.json @@ -660,5 +660,10 @@ "title": "Panel Tests - Timeseries - Out of range", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2beta1.json index b0ee8fe1273..e868bafcffd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-out-of-rage.v42.v2beta1.json @@ -676,5 +676,10 @@ "title": "Panel Tests - Timeseries - Out of range", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2alpha1.json index 19003b3c112..dbe2ae22ebd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2alpha1.json @@ -821,5 +821,10 @@ "title": "Panel Tests - shared tooltips cursor positioning", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2beta1.json index 17006d8b0ac..5763494659d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-shared-tooltip-cursor-position.v42.v2beta1.json @@ -839,5 +839,10 @@ "title": "Panel Tests - shared tooltips cursor positioning", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2alpha1.json index 91ebfa89a29..3c8700d1c0a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2alpha1.json @@ -2849,5 +2849,10 @@ "title": "Panel Tests - Graph NG - softMin/softMax", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2beta1.json index b616f35f02f..5cd6604807a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-soft-limits.v42.v2beta1.json @@ -2887,5 +2887,10 @@ "title": "Panel Tests - Graph NG - softMin/softMax", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2alpha1.json index d5de67f8b7e..59b356d1a36 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2alpha1.json @@ -1521,5 +1521,10 @@ "title": "Panel Tests - TimeSeries - stacking", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2beta1.json index b14bc2dfae4..07c5f127c32 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking.v42.v2beta1.json @@ -1566,5 +1566,10 @@ "title": "Panel Tests - TimeSeries - stacking", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2alpha1.json index c37056e01ec..4c92eef28c1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2alpha1.json @@ -4629,5 +4629,10 @@ "title": "TimeSeries \u0026 BarChart Stacking", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2beta1.json index 200a8362e4e..486f41cdce0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-stacking2.v42.v2beta1.json @@ -4818,5 +4818,10 @@ "title": "TimeSeries \u0026 BarChart Stacking", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2alpha1.json index 99bf0a4bba4..b15dedc73a8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2alpha1.json @@ -176,6 +176,88 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "critical", + "fill": false, + "line": true, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "warning", + "fill": false, + "line": true, + "op": "gt", + "value": 50, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -339,6 +421,88 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:109", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "lt", + "value": 20, + "yaxis": "left" + }, + { + "$$hashKey": "object:115", + "colorMode": "warning", + "fill": true, + "line": true, + "op": "lt", + "value": 60, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -826,6 +990,88 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "warning", + "fill": true, + "line": true, + "op": "gt", + "value": 50, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -876,6 +1122,88 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:109", + "colorMode": "critical", + "fill": true, + "line": false, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:115", + "colorMode": "warning", + "fill": true, + "line": false, + "op": "gt", + "value": 60, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -928,6 +1256,97 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 0, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "warning", + "fill": true, + "line": true, + "op": "lt", + "value": 40, + "yaxis": "left" + }, + { + "$$hashKey": "object:40", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "lt", + "value": 20, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -980,6 +1399,92 @@ "spec": { "pluginVersion": "7.5.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 0, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(50, 161, 230, 0.13)", + "line": true, + "lineColor": "#B877D9", + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(184, 119, 217, 0.23)", + "line": true, + "lineColor": "rgba(93, 196, 31, 0.6)", + "op": "lt", + "value": 40, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -1185,5 +1690,10 @@ "title": "Panel Tests - GraphNG Thresholds", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2beta1.json index d1f32f0900d..0e9b32d82cf 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-thresholds.v42.v2beta1.json @@ -182,6 +182,88 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "critical", + "fill": false, + "line": true, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "warning", + "fill": false, + "line": true, + "op": "gt", + "value": 50, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -349,6 +431,88 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:109", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "lt", + "value": 20, + "yaxis": "left" + }, + { + "$$hashKey": "object:115", + "colorMode": "warning", + "fill": true, + "line": true, + "op": "lt", + "value": 60, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -846,6 +1010,88 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "warning", + "fill": true, + "line": true, + "op": "gt", + "value": 50, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -898,6 +1144,88 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:109", + "colorMode": "critical", + "fill": true, + "line": false, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:115", + "colorMode": "warning", + "fill": true, + "line": false, + "op": "gt", + "value": 60, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -952,6 +1280,97 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 0, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "warning", + "fill": true, + "line": true, + "op": "lt", + "value": 40, + "yaxis": "left" + }, + { + "$$hashKey": "object:40", + "colorMode": "critical", + "fill": true, + "line": true, + "op": "lt", + "value": 20, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -1006,6 +1425,92 @@ "version": "7.5.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 0, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 1, + "points": true, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [ + { + "$$hashKey": "object:14", + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(50, 161, 230, 0.13)", + "line": true, + "lineColor": "#B877D9", + "op": "gt", + "value": 80, + "yaxis": "left" + }, + { + "$$hashKey": "object:44", + "colorMode": "custom", + "fill": true, + "fillColor": "rgba(184, 119, 217, 0.23)", + "line": true, + "lineColor": "rgba(93, 196, 31, 0.6)", + "op": "lt", + "value": 40, + "yaxis": "left" + } + ], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:26", + "format": "short", + "logBase": 1, + "max": "100", + "min": "0", + "show": true + }, + { + "$$hashKey": "object:27", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "alertThreshold": true }, "fieldConfig": { @@ -1211,5 +1716,10 @@ "title": "Panel Tests - GraphNG Thresholds", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2alpha1.json index cf0c37a3a79..43271c576dd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2alpha1.json @@ -735,5 +735,10 @@ "title": "Panel Tests - GraphNG - Time Axis", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2beta1.json index f106b3c8e1a..3674472eb53 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-time.v42.v2beta1.json @@ -749,5 +749,10 @@ "title": "Panel Tests - GraphNG - Time Axis", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2alpha1.json index 4a6a5b03287..27afd1ec327 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2alpha1.json @@ -1095,5 +1095,10 @@ "title": "Zero Decimals Y Ticks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2beta1.json index 0d41fc01b8f..ef2241fb8f3 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-y-ticks-zero-decimals.v42.v2beta1.json @@ -1121,5 +1121,10 @@ "title": "Zero Decimals Y Ticks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2alpha1.json index d23c438178c..40bf202a1ae 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2alpha1.json @@ -1722,5 +1722,10 @@ "title": "Panel Tests - Graph NG - Y axis ticks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2beta1.json index 923573205a8..6e3377b4cc4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries-yaxis-ticks.v42.v2beta1.json @@ -1765,5 +1765,10 @@ "title": "Panel Tests - Graph NG - Y axis ticks", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2alpha1.json index cb50db62a68..e50b453076a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2alpha1.json @@ -4371,5 +4371,10 @@ "title": "Panel Tests - Graph NG", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2beta1.json index 249af246ac9..65105663c85 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-timeseries/v0alpha1.timeseries.v42.v2beta1.json @@ -4445,5 +4445,10 @@ "title": "Panel Tests - Graph NG", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2alpha1.json index dda9209aa94..1439756b694 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2alpha1.json @@ -270,5 +270,10 @@ "title": "Panel Tests - Trend", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2beta1.json index 11683b31b98..65de2a79cf4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-trend/v0alpha1.trend_example.v42.v2beta1.json @@ -274,5 +274,10 @@ "title": "Panel Tests - Trend", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2alpha1.json index 53122268d1d..76278b42b57 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2alpha1.json @@ -1785,5 +1785,10 @@ "title": "Panel Tests - XY Chart Demo", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2beta1.json index a4c1b86c07e..70a7b3b7537 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-demo.v42.v2beta1.json @@ -1825,5 +1825,10 @@ "title": "Panel Tests - XY Chart Demo", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2alpha1.json index 33d0b2ee9b2..ccb0c353c72 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2alpha1.json @@ -2478,5 +2478,10 @@ "title": "Panel Tests - XY Chart migrations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2beta1.json index a43b5c5e1e9..add31528134 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-migrations.v42.v2beta1.json @@ -2515,5 +2515,10 @@ "title": "Panel Tests - XY Chart migrations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2alpha1.json index 7583af8160e..1d60f0ef9bf 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2alpha1.json @@ -885,5 +885,10 @@ "title": "XYChart tooltip color test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2beta1.json index e10e9fc65ff..5a46646474d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/panel-xychart/v0alpha1.xychart-tooltip-color-test.v42.v2beta1.json @@ -907,5 +907,10 @@ "title": "XYChart tooltip color test", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2alpha1.json index 38e58c03f3a..d203fb8e357 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2alpha1.json @@ -150,5 +150,10 @@ "title": "Mostly blank dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2beta1.json index 45c5b980f7f..8f1a85fee5f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.mostly-blank-dashboard.v42.v2beta1.json @@ -153,5 +153,10 @@ "title": "Mostly blank dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2alpha1.json index a8c0c9f5617..7e915f70e20 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2alpha1.json @@ -250,5 +250,10 @@ "title": "Panel Tests - Relative time zone support", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2beta1.json index e8b38167a2a..545a6a234b4 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.relative_time_zone_support.v42.v2beta1.json @@ -257,5 +257,10 @@ "title": "Panel Tests - Relative time zone support", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2alpha1.json index a738ad9daba..addd25f950f 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2alpha1.json @@ -86,7 +86,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -132,7 +189,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -178,7 +292,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -224,7 +395,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -270,7 +498,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -316,7 +601,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -362,7 +704,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -408,7 +807,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -454,7 +910,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -500,7 +1013,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -546,7 +1116,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -592,7 +1219,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -638,7 +1322,64 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -851,5 +1592,10 @@ "title": "Panel tests - Slow Queries \u0026 Annotations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2beta1.json index 2d018bf0db4..427a41ec1d7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.slow_queries_and_annotations.v42.v2beta1.json @@ -93,7 +93,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -142,7 +199,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -191,7 +305,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -240,7 +411,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -289,7 +517,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -338,7 +623,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -387,7 +729,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -436,7 +835,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -485,7 +941,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -534,7 +1047,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -583,7 +1153,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -632,7 +1259,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -681,7 +1365,64 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -894,5 +1635,10 @@ "title": "Panel tests - Slow Queries \u0026 Annotations", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2alpha1.json index 027ae6f3352..5fd3f355cbb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2alpha1.json @@ -3416,5 +3416,10 @@ "title": "A tall dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2beta1.json index a225f2e7d81..b0d10fd280b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.tall_dashboard.v42.v2beta1.json @@ -3517,5 +3517,10 @@ "title": "A tall dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2alpha1.json index 0d6468c31f1..f95a6880b61 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2alpha1.json @@ -108,6 +108,67 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -171,6 +232,73 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 0, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "C-series", + "steppedLine": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -217,6 +345,68 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -265,6 +455,68 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -326,6 +578,75 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "Perecent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "label": "Pressure", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -404,6 +725,73 @@ "spec": { "pluginVersion": "", "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "zindex": -3 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -532,5 +920,10 @@ "title": "Panel Tests - Time zone support", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2beta1.json index 348f2876085..46da655452b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/scenarios/v0alpha1.time_zone_support.v42.v2beta1.json @@ -119,6 +119,67 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "decimals": 3, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": true, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -187,6 +248,73 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 0, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "C-series", + "steppedLine": true + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -236,6 +364,68 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -287,6 +477,68 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -353,6 +605,75 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "Perecent", + "logBase": 1, + "show": true + }, + { + "format": "short", + "label": "Pressure", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -438,6 +759,73 @@ "version": "", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "B-series", + "zindex": -3 + } + ], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, "dataLinks": [] }, "fieldConfig": { @@ -566,5 +954,10 @@ "title": "Panel Tests - Time zone support", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2alpha1.json index 8808e6d73dc..a0e87e7d5f2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2alpha1.json @@ -1014,5 +1014,10 @@ "title": "Transforms - Config from query", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2beta1.json index 69930ae2e77..8134c573a69 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.config-from-query.v42.v2beta1.json @@ -1040,5 +1040,10 @@ "title": "Transforms - Config from query", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2alpha1.json index 469fca5d2aa..a611e5b0db2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2alpha1.json @@ -418,5 +418,10 @@ "title": "Transforms - Test extractFields JSON", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2beta1.json index 396cbc7348b..e1229efccac 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.extract-json-paths.v42.v2beta1.json @@ -428,5 +428,10 @@ "title": "Transforms - Test extractFields JSON", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2alpha1.json index 9202330a572..056fdc62383 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2alpha1.json @@ -227,5 +227,10 @@ "title": "Transforms - Filters", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2beta1.json index c9d1b8f11c4..57c5559add1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.filter.v42.v2beta1.json @@ -233,5 +233,10 @@ "title": "Transforms - Filters", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2alpha1.json index 9797be322d6..cbd2e994f15 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2alpha1.json @@ -865,5 +865,10 @@ "title": "Transforms - Join by field", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2beta1.json index ab0fb924f23..8fc053627fd 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-field.v42.v2beta1.json @@ -884,5 +884,10 @@ "title": "Transforms - Join by field", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2alpha1.json index 99353757d46..a10f2f6ed00 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2alpha1.json @@ -510,5 +510,10 @@ "title": "Transforms - Join by labels", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2beta1.json index fdc1b53ff36..73b06c4be7e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.join-by-labels.v42.v2beta1.json @@ -526,5 +526,10 @@ "title": "Transforms - Join by labels", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2alpha1.json index 22f053d066c..cab0fbea1e7 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2alpha1.json @@ -1348,5 +1348,10 @@ "title": "Transforms - Regression analysis", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2beta1.json index 0d00e3f1021..464769f0e9e 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.regression-analysis.v42.v2beta1.json @@ -1371,5 +1371,10 @@ "title": "Transforms - Regression analysis", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2alpha1.json index fdea0031183..08b35165f79 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2alpha1.json @@ -741,5 +741,10 @@ "title": "Transforms - Reuse dashboard queries", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2beta1.json index 79002c2d12c..d8db8e1ada9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.reuse.v42.v2beta1.json @@ -756,5 +756,10 @@ "title": "Transforms - Reuse dashboard queries", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2alpha1.json index 4d47c35593c..f89d509cae8 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2alpha1.json @@ -963,5 +963,10 @@ "title": "Transforms - Rows to fields", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2beta1.json index ddeb72b78f0..234f5dcbd63 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/transforms/v0alpha1.rows-to-fields.v42.v2beta1.json @@ -983,5 +983,10 @@ "title": "Transforms - Rows to fields", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2alpha1.json index b9aea52ad62..43ca604b064 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2alpha1.json @@ -665,7 +665,42 @@ "kind": "heatmap", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": false + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": false + }, + "xAxis": { + "show": true + }, + "yAxis": { + "format": "short", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1578,5 +1613,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2beta1.json index 0bd3a37b2d8..ae693615b73 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.all-panels.v42.v2beta1.json @@ -691,7 +691,42 @@ "group": "heatmap", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "heatmap", + "originalOptions": { + "cards": {}, + "color": { + "cardColor": "#b4ff00", + "colorScale": "sqrt", + "colorScheme": "interpolateOranges", + "exponent": 0.5, + "mode": "spectrum" + }, + "dataFormat": "timeseries", + "heatmap": {}, + "hideZeroBuckets": false, + "highlightCards": true, + "legend": { + "show": false + }, + "reverseYBuckets": false, + "tooltip": { + "show": true, + "showHistogram": false + }, + "xAxis": { + "show": true + }, + "yAxis": { + "format": "short", + "logBase": 1, + "show": true + }, + "yBucketBound": "auto" + } + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -1624,5 +1659,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2alpha1.json index d50e38918d2..7c77141f891 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2alpha1.json @@ -56,6 +56,14 @@ "spec": { "pluginVersion": "9.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "panel-tests" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -94,6 +102,15 @@ "spec": { "pluginVersion": "9.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "gdev", + "demo" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -133,6 +150,15 @@ "spec": { "pluginVersion": "9.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "templating", + "gdev" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -172,6 +198,15 @@ "spec": { "pluginVersion": "9.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "gdev", + "datasource-test" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -211,6 +246,12 @@ "spec": { "pluginVersion": "9.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [] + } + }, "maxItems": 100, "query": "", "showHeadings": true, @@ -247,6 +288,15 @@ "spec": { "pluginVersion": "9.0.0-pre", "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "gdev", + "demo" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -379,5 +429,10 @@ "title": "Grafana Dev Overview \u0026 Home", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2beta1.json index dc06779b135..5cec6a9741b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/migrated_dev_dashboards/v0alpha1.v1beta1.v1beta1.home.v42.v2beta1.json @@ -58,6 +58,14 @@ "version": "9.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "panel-tests" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -97,6 +105,15 @@ "version": "9.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "gdev", + "demo" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -137,6 +154,15 @@ "version": "9.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "templating", + "gdev" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -177,6 +203,15 @@ "version": "9.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "gdev", + "datasource-test" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -217,6 +252,12 @@ "version": "9.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [] + } + }, "maxItems": 100, "query": "", "showHeadings": true, @@ -254,6 +295,15 @@ "version": "9.0.0-pre", "spec": { "options": { + "__angularMigration": { + "autoMigrateFrom": "dashlist", + "originalOptions": { + "tags": [ + "gdev", + "demo" + ] + } + }, "maxItems": 1000, "query": "", "showHeadings": false, @@ -386,5 +436,10 @@ "title": "Grafana Dev Overview \u0026 Home", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v0alpha1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v0alpha1.json new file mode 100644 index 00000000000..d1253a0a81d --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v0alpha1.json @@ -0,0 +1,1310 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "angular-migrations-test" + }, + "spec": { + "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" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [ + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate graph panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate graph panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate table (old) panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate table (old) panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate piechart panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate piechart panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate worldmap panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate worldmap panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate stat panel (TRUE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate stat panel (FALSE)", + "tooltip": "", + "type": "link", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate (TRUE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Auto migrate (FALSE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=false" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Disable angular (TRUE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.disableAngular=true" + }, + { + "asDropdown": false, + "icon": "external link", + "includeVars": false, + "keepTime": false, + "tags": [], + "targetBlank": true, + "title": "Disable angular (FALSE)", + "tooltip": "", + "type": "link", + "url": "/d/cdd412c4/?__feature.disableAngular=false" + } + ], + "liveNow": false, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.0.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk", + "seriesCount": 3 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 0 + }, + "id": 6, + "options": { + "code": { + "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", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "aliasColors": {}, + "autoMigrateFrom": "graph", + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.0.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.260951647569786,\n 1.887442338051216,\n 2.1526144400893514,\n 1.7287721375237766,\n 1.7262902137793208\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod1\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 1.589539045095202,\n 1.5914283506847613,\n 1.8976990616650726,\n 1.758223085999124,\n 2.2294649594813816\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod2\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.0914263380328766,\n 1.8164545521094575,\n 1.621111084665713,\n 1.3902653996444705,\n 1.482803315949775\n ]\n ]\n }\n }\n]", + "refId": "A", + "scenarioId": "raw_frame" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph - x axis series mode", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "barchart", + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 11 + }, + "id": 29, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar chart panel\n", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "aliasColors": {}, + "autoMigrateFrom": "graph", + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "default": false, + "type": "datasource", + "uid": "-- Dashboard --" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 32, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.3.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 28, + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph - x axis series mode (with legend calcs)", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "bargauge", + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "autoMigrateFrom": "graph", + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 11, + "w": 16, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 30, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "percentage": false, + "pluginVersion": "11.0.0-pre", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk", + "seriesCount": 3 + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Flot graph - x axis histogram mode", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "histogram", + "xaxis": { + "mode": "histogram", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:193", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:194", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 22 + }, + "id": 33, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar gauge panel\n", + "mode": "markdown" + }, + "pluginVersion": "11.3.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 11, + "w": 8, + "x": 16, + "y": 22 + }, + "id": 31, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Histogram panel\n", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "table-old", + "columns": [], + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fontSize": "100%", + "gridPos": { + "h": 10, + "w": 16, + "x": 0, + "y": 33 + }, + "id": 2, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "showRowNums": false + }, + "pluginVersion": "9.5.0-pre", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "right", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk_table" + } + ], + "title": "Table (old)", + "transform": "table", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 33 + }, + "id": 7, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Table (old) \u003e\u003e Table\n\nKnown issues:\n* wrapping text\n* style changes", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "grafana-singlestat-panel", + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": { + "type": "grafana-testdata-datasource" + }, + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 43 + }, + "id": 9, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "thresholds": "", + "title": "grafana-singlestat-panel", + "type": "stat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 43 + }, + "id": 23, + "maxDataPoints": 100, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "singlestat (old, internal. Migrated if schema \u003c 28)", + "type": "stat" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 43 + }, + "id": 10, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Singlestat \u003e\u003e Stat\n\nKnown issues:\n* limited options", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "grafana-piechart-panel", + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 16, + "x": 0, + "y": 51 + }, + "id": 24, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "9.5.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "random_walk_table" + } + ], + "title": "grafana-piechart-panel", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "piechart" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 51 + }, + "id": 25, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-piechart-panel \u003e\u003e piechart\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + }, + { + "autoMigrateFrom": "grafana-worldmap-panel", + "circleMaxSize": 30, + "circleMinSize": 2, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": { + "type": "grafana-testdata-datasource" + }, + "decimals": 0, + "esMetric": "Count", + "gridPos": { + "h": 10, + "w": 16, + "x": 0, + "y": 61 + }, + "hideEmpty": false, + "hideZero": false, + "id": 26, + "initialZoom": 1, + "locationData": "countries", + "mapCenter": "(0°, 0°)", + "mapCenterLatitude": 0, + "mapCenterLongitude": 0, + "maxDataPoints": 1, + "mouseWheelZoom": false, + "options": { + "basemap": { + "name": "Basemap", + "type": "default" + }, + "controls": { + "mouseWheelZoom": false, + "showAttribution": true, + "showDebug": false, + "showMeasure": false, + "showScale": false, + "showZoom": true + }, + "layers": [ + { + "config": { + "showLegend": true, + "style": { + "color": { + "fixed": "dark-green" + }, + "opacity": 0.4, + "rotation": { + "fixed": 0, + "max": 360, + "min": -360, + "mode": "mod" + }, + "size": { + "fixed": 5, + "max": 30, + "min": 2 + }, + "symbol": { + "fixed": "img/icons/marker/circle.svg", + "mode": "fixed" + }, + "symbolAlign": { + "horizontal": "center", + "vertical": "center" + }, + "textConfig": { + "fontSize": 12, + "offsetX": 0, + "offsetY": 0, + "textAlign": "center", + "textBaseline": "middle" + } + } + }, + "location": { + "gazetteer": "public/gazetteer/countries.json", + "mode": "lookup" + }, + "name": "Layer 0", + "tooltip": true, + "type": "markers" + } + ], + "tooltip": { + "mode": "details" + }, + "view": { + "allLayers": true, + "id": "zero", + "lat": 0, + "lon": 0, + "zoom": 1 + } + }, + "pluginVersion": "10.4.0-pre", + "showLegend": true, + "stickyLabels": false, + "tableQueryOptions": { + "geohashField": "geohash", + "latitudeField": "latitude", + "longitudeField": "longitude", + "metricField": "metric", + "queryType": "geohash" + }, + "targets": [ + { + "csvFileName": "flight_info_by_state.csv", + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A", + "scenarioId": "csv_file" + } + ], + "thresholds": "0,10", + "title": "grafana-worldmap-panel", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + }, + { + "id": "reduce", + "options": { + "reducers": [ + "sum" + ] + } + } + ], + "type": "geomap", + "unitPlural": "", + "unitSingle": "", + "valueName": "total" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "gridPos": { + "h": 10, + "w": 8, + "x": 16, + "y": 61 + }, + "id": 27, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-worldmap-panel \u003e\u003e geomap\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "pluginVersion": "11.0.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "refId": "A" + } + ], + "title": "Status + Notes", + "type": "text" + } + ], + "refresh": "", + "schemaVersion": 42, + "tags": [ + "gdev", + "migrations", + "angular" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Devenv - Panel migrations", + "uid": "cdd412c4", + "weekStart": "" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v2alpha1.json new file mode 100644 index 00000000000..d9e72ec700a --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v2alpha1.json @@ -0,0 +1,1861 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "angular-migrations-test" + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "query": { + "kind": "grafana", + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-10": { + "kind": "Panel", + "spec": { + "id": 10, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Singlestat \u003e\u003e Stat\n\nKnown issues:\n* limited options", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Table (old)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": { + "scenarioId": "random_walk_table" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "merge", + "spec": { + "id": "merge", + "options": { + "reducers": [] + } + } + } + ], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "table", + "spec": { + "pluginVersion": "9.5.0-pre", + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "right", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + }, + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "showRowNums": false + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-23": { + "kind": "Panel", + "spec": { + "id": 23, + "title": "singlestat (old, internal. Migrated if schema \u003c 28)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "maxDataPoints": 100 + } + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "ms", + "mappings": [ + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "N/A" + } + } + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": null, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + } + }, + "overrides": [] + } + } + } + } + }, + "panel-24": { + "kind": "Panel", + "spec": { + "id": 24, + "title": "grafana-piechart-panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": { + "scenarioId": "random_walk_table" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "merge", + "spec": { + "id": "merge", + "options": { + "reducers": [] + } + } + } + ], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "piechart", + "spec": { + "pluginVersion": "9.5.0-pre", + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-piechart-panel", + "originalOptions": {} + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-25": { + "kind": "Panel", + "spec": { + "id": 25, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-piechart-panel \u003e\u003e piechart\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-26": { + "kind": "Panel", + "spec": { + "id": 26, + "title": "grafana-worldmap-panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": { + "csvFileName": "flight_info_by_state.csv", + "scenarioId": "csv_file" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "merge", + "spec": { + "id": "merge", + "options": { + "reducers": [] + } + } + }, + { + "kind": "reduce", + "spec": { + "id": "reduce", + "options": { + "reducers": [ + "sum" + ] + } + } + } + ], + "queryOptions": { + "maxDataPoints": 1 + } + } + }, + "vizConfig": { + "kind": "geomap", + "spec": { + "pluginVersion": "10.4.0-pre", + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-worldmap-panel", + "originalOptions": { + "circleMaxSize": 30, + "circleMinSize": 2, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 0, + "esMetric": "Count", + "hideEmpty": false, + "hideZero": false, + "initialZoom": 1, + "locationData": "countries", + "mapCenter": "(0°, 0°)", + "mapCenterLatitude": 0, + "mapCenterLongitude": 0, + "mouseWheelZoom": false, + "showLegend": true, + "stickyLabels": false, + "tableQueryOptions": { + "geohashField": "geohash", + "latitudeField": "latitude", + "longitudeField": "longitude", + "metricField": "metric", + "queryType": "geohash" + }, + "thresholds": "0,10", + "unitPlural": "", + "unitSingle": "", + "valueName": "total" + } + }, + "basemap": { + "name": "Basemap", + "type": "default" + }, + "controls": { + "mouseWheelZoom": false, + "showAttribution": true, + "showDebug": false, + "showMeasure": false, + "showScale": false, + "showZoom": true + }, + "layers": [ + { + "config": { + "showLegend": true, + "style": { + "color": { + "fixed": "dark-green" + }, + "opacity": 0.4, + "rotation": { + "fixed": 0, + "max": 360, + "min": -360, + "mode": "mod" + }, + "size": { + "fixed": 5, + "max": 30, + "min": 2 + }, + "symbol": { + "fixed": "img/icons/marker/circle.svg", + "mode": "fixed" + }, + "symbolAlign": { + "horizontal": "center", + "vertical": "center" + }, + "textConfig": { + "fontSize": 12, + "offsetX": 0, + "offsetY": 0, + "textAlign": "center", + "textBaseline": "middle" + } + } + }, + "location": { + "gazetteer": "public/gazetteer/countries.json", + "mode": "lookup" + }, + "name": "Layer 0", + "tooltip": true, + "type": "markers" + } + ], + "tooltip": { + "mode": "details" + }, + "view": { + "allLayers": true, + "id": "zero", + "lat": 0, + "lon": 0, + "zoom": 1 + } + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-27": { + "kind": "Panel", + "spec": { + "id": 27, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-worldmap-panel \u003e\u003e geomap\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-28": { + "kind": "Panel", + "spec": { + "id": 28, + "title": "Flot graph - x axis series mode", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": { + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.260951647569786,\n 1.887442338051216,\n 2.1526144400893514,\n 1.7287721375237766,\n 1.7262902137793208\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod1\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 1.589539045095202,\n 1.5914283506847613,\n 1.8976990616650726,\n 1.758223085999124,\n 2.2294649594813816\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod2\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.0914263380328766,\n 1.8164545521094575,\n 1.621111084665713,\n 1.3902653996444705,\n 1.482803315949775\n ]\n ]\n }\n }\n]", + "scenarioId": "raw_frame" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "barchart", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-29": { + "kind": "Panel", + "spec": { + "id": 29, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar chart panel\n", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-30": { + "kind": "Panel", + "spec": { + "id": 30, + "title": "Flot graph - x axis histogram mode", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": { + "scenarioId": "random_walk", + "seriesCount": 3 + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "histogram", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "histogram", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:193", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:194", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-31": { + "kind": "Panel", + "spec": { + "id": 31, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Histogram panel\n", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-32": { + "kind": "Panel", + "spec": { + "id": 32, + "title": "Flot graph - x axis series mode (with legend calcs)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 28 + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "bargauge", + "spec": { + "pluginVersion": "11.3.0-pre", + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-33": { + "kind": "Panel", + "spec": { + "id": 33, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.3.0-pre", + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar gauge panel\n", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "Flot graph", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": { + "scenarioId": "random_walk", + "seriesCount": 3 + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "code": { + "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" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "text", + "spec": { + "pluginVersion": "11.0.0-pre", + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Table (old) \u003e\u003e Table\n\nKnown issues:\n* wrapping text\n* style changes", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-9": { + "kind": "Panel", + "spec": { + "id": 9, + "title": "grafana-singlestat-panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "maxDataPoints": 100 + } + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-singlestat-panel", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 0, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 11, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-28" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 11, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-29" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 22, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-32" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 22, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-30" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 22, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-33" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 22, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-31" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 33, + "width": 16, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 33, + "width": 8, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-7" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 43, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-9" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 8, + "y": 43, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-23" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 43, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-10" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 51, + "width": 16, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-24" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 51, + "width": 8, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-25" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 61, + "width": 16, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-26" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 61, + "width": 8, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-27" + } + } + } + ] + } + }, + "links": [ + { + "title": "Auto migrate graph panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate graph panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate table (old) panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate table (old) panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate piechart panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate piechart panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate worldmap panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate worldmap panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate stat panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate stat panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Disable angular (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.disableAngular=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Disable angular (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.disableAngular=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + } + ], + "liveNow": false, + "preload": false, + "tags": [ + "gdev", + "migrations", + "angular" + ], + "timeSettings": { + "timezone": "", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Devenv - Panel migrations", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v2beta1.json new file mode 100644 index 00000000000..63447487dca --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.angular-migrations.v2beta1.json @@ -0,0 +1,1912 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2beta1", + "metadata": { + "name": "angular-migrations-test" + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-10": { + "kind": "Panel", + "spec": { + "id": 10, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.0.0-pre", + "spec": { + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Singlestat \u003e\u003e Stat\n\nKnown issues:\n* limited options", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Table (old)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": { + "scenarioId": "random_walk_table" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "merge", + "spec": { + "id": "merge", + "options": { + "reducers": [] + } + } + } + ], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "table", + "version": "9.5.0-pre", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "table-old", + "originalOptions": { + "columns": [], + "fontSize": "100%", + "showHeader": true, + "sort": { + "col": 0, + "desc": true + }, + "styles": [ + { + "alias": "Time", + "align": "auto", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "pattern": "Time", + "type": "date" + }, + { + "alias": "", + "align": "right", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 2, + "pattern": "/.*/", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "transform": "table" + } + }, + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true, + "showRowNums": false + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-23": { + "kind": "Panel", + "spec": { + "id": 23, + "title": "singlestat (old, internal. Migrated if schema \u003c 28)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "maxDataPoints": 100 + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "11.0.0-pre", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "unit": "ms", + "mappings": [ + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "N/A" + } + } + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": null, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + } + }, + "overrides": [] + } + } + } + } + }, + "panel-24": { + "kind": "Panel", + "spec": { + "id": 24, + "title": "grafana-piechart-panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": { + "scenarioId": "random_walk_table" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "merge", + "spec": { + "id": "merge", + "options": { + "reducers": [] + } + } + } + ], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "piechart", + "version": "9.5.0-pre", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-piechart-panel", + "originalOptions": {} + }, + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "pieType": "pie", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-25": { + "kind": "Panel", + "spec": { + "id": 25, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.0.0-pre", + "spec": { + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-piechart-panel \u003e\u003e piechart\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-26": { + "kind": "Panel", + "spec": { + "id": 26, + "title": "grafana-worldmap-panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": { + "csvFileName": "flight_info_by_state.csv", + "scenarioId": "csv_file" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [ + { + "kind": "merge", + "spec": { + "id": "merge", + "options": { + "reducers": [] + } + } + }, + { + "kind": "reduce", + "spec": { + "id": "reduce", + "options": { + "reducers": [ + "sum" + ] + } + } + } + ], + "queryOptions": { + "maxDataPoints": 1 + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "geomap", + "version": "10.4.0-pre", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-worldmap-panel", + "originalOptions": { + "circleMaxSize": 30, + "circleMinSize": 2, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "decimals": 0, + "esMetric": "Count", + "hideEmpty": false, + "hideZero": false, + "initialZoom": 1, + "locationData": "countries", + "mapCenter": "(0°, 0°)", + "mapCenterLatitude": 0, + "mapCenterLongitude": 0, + "mouseWheelZoom": false, + "showLegend": true, + "stickyLabels": false, + "tableQueryOptions": { + "geohashField": "geohash", + "latitudeField": "latitude", + "longitudeField": "longitude", + "metricField": "metric", + "queryType": "geohash" + }, + "thresholds": "0,10", + "unitPlural": "", + "unitSingle": "", + "valueName": "total" + } + }, + "basemap": { + "name": "Basemap", + "type": "default" + }, + "controls": { + "mouseWheelZoom": false, + "showAttribution": true, + "showDebug": false, + "showMeasure": false, + "showScale": false, + "showZoom": true + }, + "layers": [ + { + "config": { + "showLegend": true, + "style": { + "color": { + "fixed": "dark-green" + }, + "opacity": 0.4, + "rotation": { + "fixed": 0, + "max": 360, + "min": -360, + "mode": "mod" + }, + "size": { + "fixed": 5, + "max": 30, + "min": 2 + }, + "symbol": { + "fixed": "img/icons/marker/circle.svg", + "mode": "fixed" + }, + "symbolAlign": { + "horizontal": "center", + "vertical": "center" + }, + "textConfig": { + "fontSize": 12, + "offsetX": 0, + "offsetY": 0, + "textAlign": "center", + "textBaseline": "middle" + } + } + }, + "location": { + "gazetteer": "public/gazetteer/countries.json", + "mode": "lookup" + }, + "name": "Layer 0", + "tooltip": true, + "type": "markers" + } + ], + "tooltip": { + "mode": "details" + }, + "view": { + "allLayers": true, + "id": "zero", + "lat": 0, + "lon": 0, + "zoom": 1 + } + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-27": { + "kind": "Panel", + "spec": { + "id": 27, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.0.0-pre", + "spec": { + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# grafana-worldmap-panel \u003e\u003e geomap\n\nKnown issues:\n* TBD", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-28": { + "kind": "Panel", + "spec": { + "id": 28, + "title": "Flot graph - x axis series mode", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": { + "rawFrameContent": "[\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.260951647569786,\n 1.887442338051216,\n 2.1526144400893514,\n 1.7287721375237766,\n 1.7262902137793208\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod1\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 1.589539045095202,\n 1.5914283506847613,\n 1.8976990616650726,\n 1.758223085999124,\n 2.2294649594813816\n ]\n ]\n }\n },\n {\n \"schema\": {\n \"refId\": \"A\",\n \"meta\": {\n \"typeVersion\": [\n 0,\n 0\n ],\n \"custom\": {\n \"customStat\": 10\n }\n },\n \"fields\": [\n {\n \"name\": \"time\",\n \"type\": \"time\",\n \"typeInfo\": {\n \"frame\": \"time.Time\",\n \"nullable\": true\n },\n \"config\": {\n \"interval\": 3600000\n }\n },\n {\n \"name\": \"Value\",\n \"type\": \"number\",\n \"typeInfo\": {\n \"frame\": \"float64\",\n \"nullable\": true\n },\n \"labels\": {\n \"pod\": \"A-pod2\"\n },\n \"config\": {}\n }\n ]\n },\n \"data\": {\n \"values\": [\n [\n 1727107111901,\n 1727110711901,\n 1727114311901,\n 1727117911901,\n 1727121511901,\n 1727125111901\n ],\n [\n 1.907286825122581,\n 2.0914263380328766,\n 1.8164545521094575,\n 1.621111084665713,\n 1.3902653996444705,\n 1.482803315949775\n ]\n ]\n }\n }\n]", + "scenarioId": "raw_frame" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "barchart", + "version": "11.0.0-pre", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-29": { + "kind": "Panel", + "spec": { + "id": 29, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.0.0-pre", + "spec": { + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar chart panel\n", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-30": { + "kind": "Panel", + "spec": { + "id": 30, + "title": "Flot graph - x axis histogram mode", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": { + "scenarioId": "random_walk", + "seriesCount": 3 + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "histogram", + "version": "11.0.0-pre", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "histogram", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:193", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:194", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-31": { + "kind": "Panel", + "spec": { + "id": 31, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.0.0-pre", + "spec": { + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Histogram panel\n", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-32": { + "kind": "Panel", + "spec": { + "id": 32, + "title": "Flot graph - x axis series mode (with legend calcs)", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 28 + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "bargauge", + "version": "11.3.0-pre", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": true, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "series", + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "$$hashKey": "object:88", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:89", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-33": { + "kind": "Panel", + "spec": { + "id": 33, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.3.0-pre", + "spec": { + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Graph panel \u003e\u003e Bar gauge panel\n", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "Flot graph", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": { + "scenarioId": "random_walk", + "seriesCount": 3 + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "11.0.0-pre", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "fill": 1, + "fillGradient": 0, + "hiddenSeries": false, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "thresholds": [], + "timeRegions": [], + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + }, + "alertThreshold": true, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "short" + }, + "overrides": [] + } + } + } + } + }, + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.0.0-pre", + "spec": { + "options": { + "code": { + "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" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Status + Notes", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "text", + "version": "11.0.0-pre", + "spec": { + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Table (old) \u003e\u003e Table\n\nKnown issues:\n* wrapping text\n* style changes", + "mode": "markdown" + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + }, + "panel-9": { + "kind": "Panel", + "spec": { + "id": 9, + "title": "grafana-singlestat-panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana-testdata-datasource", + "version": "v0", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": { + "maxDataPoints": 100 + } + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": { + "__angularMigration": { + "autoMigrateFrom": "grafana-singlestat-panel", + "originalOptions": { + "colorBackground": false, + "colorValue": true, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "format": "areaF2", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "nullPointMode": "connected", + "postfix": "b", + "postfixFontSize": "50%", + "prefix": "a", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "thresholds": "", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + } + }, + "fieldConfig": { + "defaults": {}, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 0, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 11, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-28" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 11, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-29" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 22, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-32" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 22, + "width": 16, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-30" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 22, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-33" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 22, + "width": 8, + "height": 11, + "element": { + "kind": "ElementReference", + "name": "panel-31" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 33, + "width": 16, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 33, + "width": 8, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-7" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 43, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-9" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 8, + "y": 43, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-23" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 43, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-10" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 51, + "width": 16, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-24" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 51, + "width": 8, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-25" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 61, + "width": 16, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-26" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 16, + "y": 61, + "width": 8, + "height": 10, + "element": { + "kind": "ElementReference", + "name": "panel-27" + } + } + } + ] + } + }, + "links": [ + { + "title": "Auto migrate graph panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate graph panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateGraphPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate table (old) panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate table (old) panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateTablePanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate piechart panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate piechart panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigratePiechartPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate worldmap panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate worldmap panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateWorldmapPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate stat panel (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate stat panel (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": " /d/cdd412c4/?__feature.autoMigrateStatPanel=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Auto migrate (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.autoMigrateOldPanels=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Disable angular (TRUE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.disableAngular=true", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + }, + { + "title": "Disable angular (FALSE)", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "/d/cdd412c4/?__feature.disableAngular=false", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + } + ], + "liveNow": false, + "preload": false, + "tags": [ + "gdev", + "migrations", + "angular" + ], + "timeSettings": { + "timezone": "", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Devenv - Panel migrations", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2alpha1.json index 387ba145494..5f94f0d555b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2alpha1.json @@ -335,5 +335,10 @@ "title": "Annotation Conversions Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2beta1.json index a4dde4d26ac..c728d8dd513 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.annotation-conversions.v2beta1.json @@ -346,5 +346,10 @@ "title": "Annotation Conversions Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v0alpha1.json new file mode 100644 index 00000000000..449e76f1173 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v0alpha1.json @@ -0,0 +1,161 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "bom-in-links-test", + "namespace": "org-1", + "labels": { + "test": "bom-stripping" + } + }, + "spec": { + "description": "Testing that BOM characters are stripped from URLs during conversion", + "editable": true, + "links": [ + { + "icon": "external link", + "targetBlank": true, + "title": "Dashboard link with BOM", + "type": "link", + "url": "http://example.com?var=${datasource}\u0026other=value" + } + ], + "panels": [ + { + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "server" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Override link with BOM", + "url": "http://localhost:3000/d/test?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "links": [ + { + "targetBlank": true, + "title": "Panel data link with BOM", + "url": "http://example.com/${__data.fields.cluster}\u0026var=value" + } + ], + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "test-ds" + }, + "refId": "A" + } + ], + "title": "Panel with BOM in field config override links", + "type": "table" + }, + { + "fieldConfig": { + "defaults": { + "links": [ + { + "targetBlank": false, + "title": "Field config default link with BOM", + "url": "http://example.com?field=${__field.name}\u0026value=${__value.raw}" + } + ] + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "options": { + "dataLinks": [ + { + "targetBlank": true, + "title": "Options data link with BOM", + "url": "http://example.com?series=${__series.name}\u0026time=${__value.time}" + } + ], + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "test-ds" + }, + "refId": "A" + } + ], + "title": "Panel with BOM in options dataLinks", + "type": "timeseries" + } + ], + "schemaVersion": 42, + "tags": [ + "test", + "bom" + ], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m" + ] + }, + "title": "BOM Stripping Test Dashboard" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v2alpha1.json new file mode 100644 index 00000000000..38547ea5b8e --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v2alpha1.json @@ -0,0 +1,242 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "bom-in-links-test", + "namespace": "org-1", + "labels": { + "test": "bom-stripping" + } + }, + "spec": { + "annotations": [], + "cursorSync": "Off", + "description": "Testing that BOM characters are stripped from URLs during conversion", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Panel with BOM in field config override links", + "description": "", + "links": [ + { + "title": "Panel data link with BOM", + "url": "http://example.com/${__data.fields.cluster}\u0026var=value", + "targetBlank": true + } + ], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": {} + }, + "datasource": { + "type": "prometheus", + "uid": "test-ds" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "table", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": null, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "server" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Override link with BOM", + "url": "http://localhost:3000/d/test?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}" + } + ] + } + ] + } + ] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Panel with BOM in options dataLinks", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": {} + }, + "datasource": { + "type": "prometheus", + "uid": "test-ds" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "", + "options": { + "dataLinks": [ + { + "targetBlank": true, + "title": "Options data link with BOM", + "url": "http://example.com?series=${__series.name}\u0026time=${__value.time}" + } + ], + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + } + }, + "fieldConfig": { + "defaults": { + "links": [ + { + "targetBlank": false, + "title": "Field config default link with BOM", + "url": "http://example.com?field=${__field.name}\u0026value=${__value.raw}" + } + ] + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + } + ] + } + }, + "links": [ + { + "title": "Dashboard link with BOM", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "http://example.com?var=${datasource}\u0026other=value", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + } + ], + "liveNow": false, + "preload": false, + "tags": [ + "test", + "bom" + ], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "BOM Stripping Test Dashboard", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v2beta1.json new file mode 100644 index 00000000000..d85da89fe7a --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.bom-in-links.v2beta1.json @@ -0,0 +1,246 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2beta1", + "metadata": { + "name": "bom-in-links-test", + "namespace": "org-1", + "labels": { + "test": "bom-stripping" + } + }, + "spec": { + "annotations": [], + "cursorSync": "Off", + "description": "Testing that BOM characters are stripped from URLs during conversion", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Panel with BOM in field config override links", + "description": "", + "links": [ + { + "title": "Panel data link with BOM", + "url": "http://example.com/${__data.fields.cluster}\u0026var=value", + "targetBlank": true + } + ], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "test-ds" + }, + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "table", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": null, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "server" + }, + "properties": [ + { + "id": "links", + "value": [ + { + "title": "Override link with BOM", + "url": "http://localhost:3000/d/test?var-datacenter=${__data.fields[datacenter]}\u0026var-server=${__value.raw}" + } + ] + } + ] + } + ] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Panel with BOM in options dataLinks", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "test-ds" + }, + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "", + "spec": { + "options": { + "dataLinks": [ + { + "targetBlank": true, + "title": "Options data link with BOM", + "url": "http://example.com?series=${__series.name}\u0026time=${__value.time}" + } + ], + "legend": { + "displayMode": "list", + "placement": "bottom", + "showLegend": true + } + }, + "fieldConfig": { + "defaults": { + "links": [ + { + "targetBlank": false, + "title": "Field config default link with BOM", + "url": "http://example.com?field=${__field.name}\u0026value=${__value.raw}" + } + ] + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + } + ] + } + }, + "links": [ + { + "title": "Dashboard link with BOM", + "type": "link", + "icon": "external link", + "tooltip": "", + "url": "http://example.com?var=${datasource}\u0026other=value", + "tags": [], + "asDropdown": false, + "targetBlank": true, + "includeVars": false, + "keepTime": false + } + ], + "liveNow": false, + "preload": false, + "tags": [ + "test", + "bom" + ], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "BOM Stripping Test Dashboard", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2alpha1.json index 3e9132d9ea9..4de46378b53 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2alpha1.json @@ -200,5 +200,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2beta1.json index 951eeaac0f6..7576414d605 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.dashboard-properties.v2beta1.json @@ -205,5 +205,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v0alpha1.json new file mode 100644 index 00000000000..463d1864dce --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v0alpha1.json @@ -0,0 +1,172 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "groupby-test" + }, + "spec": { + "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" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "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": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "editorMode": "code", + "expr": "sum(counters_requests)", + "legendFormat": "__auto", + "range": true, + "refId": "A" + } + ], + "title": "works with group by var", + "type": "timeseries" + } + ], + "preload": false, + "schemaVersion": 42, + "tags": [], + "templating": { + "list": [ + { + "current": { + "text": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ], + "value": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ] + }, + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "name": "Group by", + "type": "groupby" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "groupby test", + "weekStart": "" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v2alpha1.json new file mode 100644 index 00000000000..58bf555354c --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v2alpha1.json @@ -0,0 +1,229 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "groupby-test" + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "query": { + "kind": "grafana", + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "works with group by var", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "editorMode": "code", + "expr": "sum(counters_requests)", + "legendFormat": "__auto", + "range": true + } + }, + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "12.4.0-pre", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "groupby test", + "variables": [ + { + "kind": "GroupByVariable", + "spec": { + "name": "Group by", + "datasource": { + "type": "prometheus", + "uid": "test-uid" + }, + "current": { + "text": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ], + "value": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ] + }, + "options": [], + "multi": true, + "hide": "dontHide", + "skipUrlSync": false + } + } + ] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v2beta1.json new file mode 100644 index 00000000000..c2ac16a874c --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.groupby.v2beta1.json @@ -0,0 +1,232 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v2beta1", + "metadata": { + "name": "groupby-test" + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "works with group by var", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "test-uid" + }, + "spec": { + "editorMode": "code", + "expr": "sum(counters_requests)", + "legendFormat": "__auto", + "range": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "12.4.0-pre", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "groupby test", + "variables": [ + { + "kind": "GroupByVariable", + "group": "prometheus", + "datasource": { + "name": "test-uid" + }, + "spec": { + "name": "Group by", + "current": { + "text": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ], + "value": [ + "a_legacy_label", + "app", + "exported_instance", + "exported_job" + ] + }, + "options": [], + "multi": true, + "hide": "dontHide", + "skipUrlSync": false + } + } + ] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v0alpha1.json new file mode 100644 index 00000000000..9c6354b2319 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v0alpha1.json @@ -0,0 +1,294 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "legacy-ds-ref" + }, + "spec": { + "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" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "panels": [ + { + "datasource": "${datasource}", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Minimum cluster size" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 1 + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 0, + "y": 0 + }, + "id": 16, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "editorMode": "code", + "expr": "count by (version) (alloy_build_info{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\"})", + "instant": false, + "legendFormat": "{{version}}", + "range": true, + "refId": "B" + } + ], + "title": "Number of Alloy Instances", + "type": "timeseries" + }, + { + "datasource": "${datasource}", + "description": "CPU usage of the Alloy process relative to 1 CPU core.\n\nFor example, 100% means using one entire CPU core.\n", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "Total" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": true + } + } + ] + } + ] + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 8, + "y": 0 + }, + "id": 17, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": "${datasource}", + "expr": "rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])\n", + "hide": true, + "instant": false, + "legendFormat": "{{instance}}", + "range": true, + "refId": "A" + }, + { + "datasource": "${datasource}", + "editorMode": "code", + "expr": "sum(rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "Total", + "range": true, + "refId": "B" + } + ], + "title": "CPU usage", + "type": "timeseries" + } + ], + "time": { + "from": "now-90m", + "to": "now" + }, + "timezone": "utc", + "title": "Legacy DS Panel Query Ref", + "weekStart": "" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v2alpha1.json new file mode 100644 index 00000000000..23affbf4d4a --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v2alpha1.json @@ -0,0 +1,405 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "legacy-ds-ref" + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "query": { + "kind": "grafana", + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-16": { + "kind": "Panel", + "spec": { + "id": 16, + "title": "Number of Alloy Instances", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "", + "spec": { + "editorMode": "code", + "expr": "count by (version) (alloy_build_info{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\"})", + "instant": false, + "legendFormat": "{{version}}", + "range": true + } + }, + "datasource": { + "type": "", + "uid": "${datasource}" + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Minimum cluster size" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 1 + } + ] + } + ] + } + } + } + } + }, + "panel-17": { + "kind": "Panel", + "spec": { + "id": 17, + "title": "CPU usage", + "description": "CPU usage of the Alloy process relative to 1 CPU core.\n\nFor example, 100% means using one entire CPU core.\n", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "", + "spec": { + "expr": "rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])\n", + "instant": false, + "legendFormat": "{{instance}}", + "range": true + } + }, + "datasource": { + "type": "", + "uid": "${datasource}" + }, + "refId": "A", + "hidden": true + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "", + "spec": { + "editorMode": "code", + "expr": "sum(rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "Total", + "range": true + } + }, + "datasource": { + "type": "", + "uid": "${datasource}" + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "Total" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": true + } + } + ] + } + ] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 8, + "height": 9, + "element": { + "kind": "ElementReference", + "name": "panel-16" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 8, + "y": 0, + "width": 8, + "height": 9, + "element": { + "kind": "ElementReference", + "name": "panel-17" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "utc", + "from": "now-90m", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Legacy DS Panel Query Ref", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v2beta1.json new file mode 100644 index 00000000000..758ffd9c348 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.legacy-ds-ref.v2beta1.json @@ -0,0 +1,411 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2beta1", + "metadata": { + "name": "legacy-ds-ref" + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-16": { + "kind": "Panel", + "spec": { + "id": 16, + "title": "Number of Alloy Instances", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "", + "version": "v0", + "datasource": { + "name": "${datasource}" + }, + "spec": { + "editorMode": "code", + "expr": "count by (version) (alloy_build_info{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\"})", + "instant": false, + "legendFormat": "{{version}}", + "range": true + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Minimum cluster size" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "red", + "mode": "fixed" + } + }, + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 10 + ], + "fill": "dash" + } + }, + { + "id": "custom.lineWidth", + "value": 1 + } + ] + } + ] + } + } + } + } + }, + "panel-17": { + "kind": "Panel", + "spec": { + "id": 17, + "title": "CPU usage", + "description": "CPU usage of the Alloy process relative to 1 CPU core.\n\nFor example, 100% means using one entire CPU core.\n", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "", + "version": "v0", + "datasource": { + "name": "${datasource}" + }, + "spec": { + "expr": "rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval])\n", + "instant": false, + "legendFormat": "{{instance}}", + "range": true + } + }, + "refId": "A", + "hidden": true + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "", + "version": "v0", + "datasource": { + "name": "${datasource}" + }, + "spec": { + "editorMode": "code", + "expr": "sum(rate(alloy_resources_process_cpu_seconds_total{cluster=~\"$cluster\", namespace=~\"$namespace\", job=~\"$job\", instance=~\"$instance\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "Total", + "range": true + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "timeCompare": false, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "unit": "percentunit", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [ + { + "__systemRef": "hideSeriesFrom", + "matcher": { + "id": "byNames", + "options": { + "mode": "exclude", + "names": [ + "Total" + ], + "prefix": "All except:", + "readOnly": true + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": false, + "tooltip": true, + "viz": true + } + } + ] + } + ] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 8, + "height": 9, + "element": { + "kind": "ElementReference", + "name": "panel-16" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 8, + "y": 0, + "width": 8, + "height": 9, + "element": { + "kind": "ElementReference", + "name": "panel-17" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "utc", + "from": "now-90m", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Legacy DS Panel Query Ref", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2alpha1.json index a614f32dda6..a9b876424be 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2alpha1.json @@ -165,5 +165,10 @@ "title": "Library Panel Repeat Options Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2beta1.json index d06d12848e6..8b2eb35cef1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.library-panel-repeat-options.v2beta1.json @@ -165,5 +165,10 @@ "title": "Library Panel Repeat Options Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2alpha1.json index 9e0d5378f9b..f1004780fb0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2alpha1.json @@ -181,7 +181,12 @@ "kind": "timeseries", "spec": { "pluginVersion": "", - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -501,5 +506,10 @@ "title": "Panel Conversions Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2beta1.json index 8eac23d96c0..84064324429 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-conversions.v2beta1.json @@ -186,7 +186,12 @@ "group": "timeseries", "version": "", "spec": { - "options": {}, + "options": { + "__angularMigration": { + "autoMigrateFrom": "graph", + "originalOptions": {} + } + }, "fieldConfig": { "defaults": {}, "overrides": [] @@ -510,5 +515,10 @@ "title": "Panel Conversions Test Dashboard", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2alpha1.json index 5a0a8e074e6..55b0af155ff 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2alpha1.json @@ -201,5 +201,10 @@ "title": "Panel ds inheritance ", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2beta1.json index 3a13853c08e..48ec1ca758b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-datasource-type-datasource.v2beta1.json @@ -204,5 +204,10 @@ "title": "Panel ds inheritance ", "variables": [] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v0alpha1.json new file mode 100644 index 00000000000..ad063633f86 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v0alpha1.json @@ -0,0 +1,161 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "ad5vfcn", + "namespace": "default", + "uid": "dlMZZl6GndU8gJLUQSmgZxXBPCNXyXhNBeQJhHXl0r4X", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-11-28T10:14:21Z", + "labels": { + "grafana.app/deprecatedInternalID": "288" + }, + "annotations": { + "grafana.app/createdBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedTimestamp": "2025-11-28T10:15:06Z" + } + }, + "spec": { + "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" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 288, + "links": [], + "panels": [ + { + "datasource": { + "type": "testdata", + "uid": "gdev-testdata" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "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": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "datasource": {}, + "queryType": "randomWalk" + }, + { + "datasource": {}, + "queryType": "randomWalk" + } + ], + "title": "New panel", + "type": "timeseries" + } + ], + "preload": false, + "schemaVersion": 42, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Panel ds inheritance ", + "uid": "ad5vfcn", + "version": 2 + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v2alpha1.json new file mode 100644 index 00000000000..a8ce2b6a42b --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v2alpha1.json @@ -0,0 +1,227 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "ad5vfcn", + "namespace": "default", + "uid": "dlMZZl6GndU8gJLUQSmgZxXBPCNXyXhNBeQJhHXl0r4X", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-11-28T10:14:21Z", + "labels": { + "grafana.app/deprecatedInternalID": "288" + }, + "annotations": { + "grafana.app/createdBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedTimestamp": "2025-11-28T10:15:06Z" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "query": { + "kind": "grafana", + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "New panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "testdata", + "spec": { + "queryType": "randomWalk" + } + }, + "datasource": { + "type": "testdata", + "uid": "gdev-testdata" + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "testdata", + "spec": { + "queryType": "randomWalk" + } + }, + "datasource": { + "type": "testdata", + "uid": "gdev-testdata" + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "12.4.0-pre", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Panel ds inheritance ", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v2beta1.json new file mode 100644 index 00000000000..c407d612154 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.panel-target-missing-refid.v2beta1.json @@ -0,0 +1,231 @@ +{ + "kind": "Dashboard", + "apiVersion": "dashboard.grafana.app/v2beta1", + "metadata": { + "name": "ad5vfcn", + "namespace": "default", + "uid": "dlMZZl6GndU8gJLUQSmgZxXBPCNXyXhNBeQJhHXl0r4X", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-11-28T10:14:21Z", + "labels": { + "grafana.app/deprecatedInternalID": "288" + }, + "annotations": { + "grafana.app/createdBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedBy": "user:eex2ofwuj0agwd", + "grafana.app/updatedTimestamp": "2025-11-28T10:15:06Z" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "New panel", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "testdata", + "version": "v0", + "datasource": { + "name": "gdev-testdata" + }, + "spec": { + "queryType": "randomWalk" + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "testdata", + "version": "v0", + "datasource": { + "name": "gdev-testdata" + }, + "spec": { + "queryType": "randomWalk" + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "timeseries", + "version": "12.4.0-pre", + "spec": { + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Panel ds inheritance ", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v0alpha1.json new file mode 100644 index 00000000000..c824b19412d --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v0alpha1.json @@ -0,0 +1,580 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + } + }, + "spec": { + "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" + } + ] + }, + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "critical": { + "color": "red", + "index": 0, + "text": "Critical!" + }, + "ok": { + "color": "green", + "index": 2, + "text": "OK" + }, + "warning": { + "color": "orange", + "index": 1, + "text": "Warning" + } + }, + "type": "value" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "targets": [ + { + "expr": "up", + "refId": "A" + } + ], + "title": "ValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 0, + "text": "Low" + }, + "to": 50 + }, + "type": "range" + }, + { + "options": { + "from": 50, + "result": { + "color": "orange", + "index": 1, + "text": "Medium" + }, + "to": 80 + }, + "type": "range" + }, + { + "options": { + "from": 80, + "result": { + "color": "red", + "index": 2, + "text": "High" + }, + "to": 100 + }, + "type": "range" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "targets": [ + { + "expr": "cpu_usage_percent", + "refId": "A" + } + ], + "title": "RangeMap Example", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "pattern": "/^error.*/", + "result": { + "color": "red", + "index": 0, + "text": "Error" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^warn.*/", + "result": { + "color": "orange", + "index": 1, + "text": "Warning" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^info.*/", + "result": { + "color": "blue", + "index": 2, + "text": "Info" + } + }, + "type": "regex" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "targets": [ + { + "expr": "log_level", + "refId": "A" + } + ], + "title": "RegexMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 0, + "text": "No Data" + } + }, + "type": "special" + }, + { + "options": { + "match": "nan", + "result": { + "color": "gray", + "index": 1, + "text": "Not a Number" + } + }, + "type": "special" + }, + { + "options": { + "match": "null+nan", + "result": { + "color": "gray", + "index": 2, + "text": "N/A" + } + }, + "type": "special" + }, + { + "options": { + "match": "true", + "result": { + "color": "green", + "index": 3, + "text": "Yes" + } + }, + "type": "special" + }, + { + "options": { + "match": "false", + "result": { + "color": "red", + "index": 4, + "text": "No" + } + }, + "type": "special" + }, + { + "options": { + "match": "empty", + "result": { + "color": "gray", + "index": 5, + "text": "Empty" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "targets": [ + { + "expr": "some_metric", + "refId": "A" + } + ], + "title": "SpecialValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "failure": { + "color": "red", + "index": 1, + "text": "Failure" + }, + "success": { + "color": "green", + "index": 0, + "text": "Success" + } + }, + "type": "value" + }, + { + "options": { + "from": 0, + "result": { + "color": "blue", + "index": 2, + "text": "In Range" + }, + "to": 100 + }, + "type": "range" + }, + { + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "color": "purple", + "index": 3, + "text": "ID Format" + } + }, + "type": "regex" + }, + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 4, + "text": "Missing" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 5, + "targets": [ + { + "expr": "combined_metric", + "refId": "A" + }, + { + "expr": "secondary_metric", + "refId": "B" + } + ], + "title": "Combined Mappings and Overrides Example", + "type": "table" + } + ], + "schemaVersion": 42, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Value Mapping and Overrides Test", + "weekStart": "" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v2alpha1.json new file mode 100644 index 00000000000..f4a950d53a6 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v2alpha1.json @@ -0,0 +1,783 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "query": { + "kind": "grafana", + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "ValueMap Example", + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "up" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "critical": { + "text": "Critical!", + "color": "red", + "index": 0 + }, + "ok": { + "text": "OK", + "color": "green", + "index": 2 + }, + "warning": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "RangeMap Example", + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "cpu_usage_percent" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "gauge", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "range", + "options": { + "from": 0, + "to": 50, + "result": { + "text": "Low", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 50, + "to": 80, + "result": { + "text": "Medium", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "range", + "options": { + "from": 80, + "to": 100, + "result": { + "text": "High", + "color": "red", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "RegexMap Example", + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "log_level" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "regex", + "options": { + "pattern": "/^error.*/", + "result": { + "text": "Error", + "color": "red", + "index": 0 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^warn.*/", + "result": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^info.*/", + "result": { + "text": "Info", + "color": "blue", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "SpecialValueMap Example", + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "some_metric" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "No Data", + "color": "gray", + "index": 0 + } + } + }, + { + "type": "special", + "options": { + "match": "nan", + "result": { + "text": "Not a Number", + "color": "gray", + "index": 1 + } + } + }, + { + "type": "special", + "options": { + "match": "null+nan", + "result": { + "text": "N/A", + "color": "gray", + "index": 2 + } + } + }, + { + "type": "special", + "options": { + "match": "true", + "result": { + "text": "Yes", + "color": "green", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "false", + "result": { + "text": "No", + "color": "red", + "index": 4 + } + } + }, + { + "type": "special", + "options": { + "match": "empty", + "result": { + "text": "Empty", + "color": "gray", + "index": 5 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Combined Mappings and Overrides Example", + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "combined_metric" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "secondary_metric" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "table", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "failure": { + "text": "Failure", + "color": "red", + "index": 1 + }, + "success": { + "text": "Success", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 0, + "to": 100, + "result": { + "text": "In Range", + "color": "blue", + "index": 2 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "text": "ID Format", + "color": "purple", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "Missing", + "color": "gray", + "index": 4 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 16, + "width": 24, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Value Mapping and Overrides Test", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v2beta1.json new file mode 100644 index 00000000000..ad492e24a6e --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.value-mapping-and-overrides.v2beta1.json @@ -0,0 +1,795 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v2beta1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "grafana", + "version": "v0", + "datasource": { + "name": "-- Grafana --" + }, + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "ValueMap Example", + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "up" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "critical": { + "text": "Critical!", + "color": "red", + "index": 0 + }, + "ok": { + "text": "OK", + "color": "green", + "index": 2 + }, + "warning": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "RangeMap Example", + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "cpu_usage_percent" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "gauge", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "range", + "options": { + "from": 0, + "to": 50, + "result": { + "text": "Low", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 50, + "to": 80, + "result": { + "text": "Medium", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "range", + "options": { + "from": 80, + "to": 100, + "result": { + "text": "High", + "color": "red", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "RegexMap Example", + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "log_level" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "regex", + "options": { + "pattern": "/^error.*/", + "result": { + "text": "Error", + "color": "red", + "index": 0 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^warn.*/", + "result": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^info.*/", + "result": { + "text": "Info", + "color": "blue", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "SpecialValueMap Example", + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "some_metric" + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "No Data", + "color": "gray", + "index": 0 + } + } + }, + { + "type": "special", + "options": { + "match": "nan", + "result": { + "text": "Not a Number", + "color": "gray", + "index": 1 + } + } + }, + { + "type": "special", + "options": { + "match": "null+nan", + "result": { + "text": "N/A", + "color": "gray", + "index": 2 + } + } + }, + { + "type": "special", + "options": { + "match": "true", + "result": { + "text": "Yes", + "color": "green", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "false", + "result": { + "text": "No", + "color": "red", + "index": 4 + } + } + }, + { + "type": "special", + "options": { + "match": "empty", + "result": { + "text": "Empty", + "color": "gray", + "index": 5 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Combined Mappings and Overrides Example", + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "combined_metric" + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "prometheus", + "version": "v0", + "datasource": { + "name": "prometheus-uid" + }, + "spec": { + "expr": "secondary_metric" + } + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "table", + "version": "", + "spec": { + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "failure": { + "text": "Failure", + "color": "red", + "index": 1 + }, + "success": { + "text": "Success", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 0, + "to": 100, + "result": { + "text": "In Range", + "color": "blue", + "index": 2 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "text": "ID Format", + "color": "purple", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "Missing", + "color": "gray", + "index": 4 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 16, + "width": 24, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Value Mapping and Overrides Test", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v0alpha1.json index 4e12e6982ef..725e658dfc2 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v0alpha1.json @@ -94,6 +94,7 @@ "query": "label_values(up, instance)", "refresh": 2, "regex": "/.*9090.*/", + "regexApplyTo": "text", "skipUrlSync": false, "sort": 1, "tagValuesQuery": "", @@ -362,6 +363,7 @@ }, "refresh": 1, "regex": "/host[0-9]+/", + "regexApplyTo": "value", "skipUrlSync": false, "sort": 2, "tagValuesQuery": "", diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2alpha1.json index c7c6c646a94..040513a3ce5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2alpha1.json @@ -110,6 +110,7 @@ } }, "regex": "/.*9090.*/", + "regexApplyTo": "text", "sort": "alphabeticalAsc", "definition": "label_values(up, instance)", "options": [ @@ -401,6 +402,7 @@ } }, "regex": "/host[0-9]+/", + "regexApplyTo": "value", "sort": "alphabeticalDesc", "definition": "terms field:@host size:100", "options": [], @@ -412,5 +414,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2beta1.json index 7b1a899d7fa..cf3ff5443c0 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v1beta1.variable-conversions.v2beta1.json @@ -111,6 +111,7 @@ } }, "regex": "/.*9090.*/", + "regexApplyTo": "text", "sort": "alphabeticalAsc", "definition": "label_values(up, instance)", "options": [ @@ -404,6 +405,7 @@ } }, "regex": "/host[0-9]+/", + "regexApplyTo": "value", "sort": "alphabeticalDesc", "definition": "terms field:@host size:100", "options": [], @@ -415,5 +417,10 @@ } ] }, - "status": {} + "status": { + "conversion": { + "failed": false, + "storedVersion": "v1beta1" + } + } } \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v0alpha1.json index e3e0747bfc4..ecb9021b96c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v0alpha1.json @@ -66,6 +66,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "description": "This panel demonstrates conditional rendering features", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v1beta1.json index 7c37ba8f8ab..35fc204793d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.complete.v1beta1.json @@ -66,6 +66,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "description": "This panel demonstrates conditional rendering features", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v0alpha1.json index e648923e684..b38cf688949 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v0alpha1.json @@ -150,6 +150,9 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -245,6 +248,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -341,6 +348,9 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource" + }, "fieldConfig": { "defaults": { "color": { @@ -400,6 +410,10 @@ "type": "stat" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { @@ -697,6 +711,146 @@ ], "title": "Mixed DS WITHOUT REFS", "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "description": "Panel with a single -- Dashboard -- datasource query", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 0, + "y": 18 + }, + "id": 7, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + } + ], + "title": "Single Dashboard DS Query", + "type": "stat" + }, + { + "datasource": { + "type": "mixed", + "uid": "-- Mixed --" + }, + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 8, + "y": 18 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 2, + "refId": "B", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 3, + "refId": "C", + "withTransforms": true + } + ], + "title": "Multiple Dashboard DS Queries", + "type": "stat" } ], "preload": false, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v1beta1.json index d2a4e93982e..0b7f512e6f1 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v1beta1.json @@ -150,6 +150,9 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -245,6 +248,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -341,6 +348,9 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource" + }, "fieldConfig": { "defaults": { "color": { @@ -400,6 +410,10 @@ "type": "stat" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { @@ -697,6 +711,146 @@ ], "title": "Mixed DS WITHOUT REFS", "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "description": "Panel with a single -- Dashboard -- datasource query", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 0, + "y": 18 + }, + "id": 7, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + } + ], + "title": "Single Dashboard DS Query", + "type": "stat" + }, + { + "datasource": { + "type": "mixed", + "uid": "-- Mixed --" + }, + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 9, + "w": 8, + "x": 8, + "y": 18 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 2, + "refId": "B", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 3, + "refId": "C", + "withTransforms": true + } + ], + "title": "Multiple Dashboard DS Queries", + "type": "stat" } ], "preload": false, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v2beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v2beta1.json index 09e35c64258..aba5db6146d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v2beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.ds-data-query.v2beta1.json @@ -879,6 +879,200 @@ } } } + }, + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Single Dashboard DS Query", + "description": "Panel with a single -- Dashboard -- datasource query", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "12.1.0-pre", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-8": { + "kind": "Panel", + "spec": { + "id": 8, + "title": "Multiple Dashboard DS Queries", + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 2, + "withTransforms": true + } + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "DataQuery", + "group": "datasource", + "version": "v0", + "datasource": { + "name": "-- Dashboard --" + }, + "spec": { + "panelId": 3, + "withTransforms": true + } + }, + "refId": "C", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "VizConfig", + "group": "stat", + "version": "12.1.0-pre", + "spec": { + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } } }, "layout": { @@ -941,6 +1135,24 @@ "name": "panel-6" } } + }, + { + "kind": "AutoGridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-7" + } + } + }, + { + "kind": "AutoGridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-8" + } + } } ] } diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v0alpha1.json index 37bbba541cd..d57c8d086a9 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v0alpha1.json @@ -14,6 +14,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v1beta1.json index 464c1d4c240..b2e7bd78dba 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2alpha1.viz-config.v1beta1.json @@ -14,6 +14,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v0alpha1.json index b942305c98d..f3b6ab864fb 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v0alpha1.json @@ -66,6 +66,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "description": "This panel demonstrates conditional rendering features", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v1beta1.json index 06f8c45bdad..e3236448c9d 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.complete.v1beta1.json @@ -66,6 +66,10 @@ "type": "row" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "description": "This panel demonstrates conditional rendering features", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v0alpha1.json index c1066edc211..33fd022e0db 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v0alpha1.json @@ -80,6 +80,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "description": "This should resolve to the grafana-testdata-datasource datasource", "fieldConfig": { "defaults": { @@ -170,6 +174,9 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch" + }, "description": "This should resolve to the first elasticsearch datasource", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v1beta1.json index 9bbd2f8f555..05d6df3537a 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.datasource-resolution.v1beta1.json @@ -80,6 +80,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "description": "This should resolve to the grafana-testdata-datasource datasource", "fieldConfig": { "defaults": { @@ -170,6 +174,9 @@ "type": "timeseries" }, { + "datasource": { + "type": "elasticsearch" + }, "description": "This should resolve to the first elasticsearch datasource", "fieldConfig": { "defaults": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v0alpha1.json index 6a418f1e21d..99bcc3e9581 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v0alpha1.json @@ -150,6 +150,9 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -245,6 +248,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -341,6 +348,9 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource" + }, "fieldConfig": { "defaults": { "color": { @@ -400,6 +410,10 @@ "type": "stat" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { @@ -697,6 +711,146 @@ ], "title": "Mixed DS WITHOUT REFS", "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "description": "Panel with a single -- Dashboard -- datasource query", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 3, + "w": 8, + "x": 0, + "y": 6 + }, + "id": 7, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + } + ], + "title": "Single Dashboard DS Query", + "type": "stat" + }, + { + "datasource": { + "type": "mixed", + "uid": "-- Mixed --" + }, + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 3, + "w": 8, + "x": 8, + "y": 6 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 2, + "refId": "B", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 3, + "refId": "C", + "withTransforms": true + } + ], + "title": "Multiple Dashboard DS Queries", + "type": "stat" } ], "preload": false, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v1beta1.json index 212dbdfd0f3..e2d54185ea5 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v1beta1.json @@ -150,6 +150,9 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -245,6 +248,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "prometheus", + "uid": "gdev-prometheus" + }, "fieldConfig": { "defaults": { "color": { @@ -341,6 +348,9 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource" + }, "fieldConfig": { "defaults": { "color": { @@ -400,6 +410,10 @@ "type": "stat" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { @@ -697,6 +711,146 @@ ], "title": "Mixed DS WITHOUT REFS", "type": "timeseries" + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "description": "Panel with a single -- Dashboard -- datasource query", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 3, + "w": 8, + "x": 0, + "y": 6 + }, + "id": 7, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + } + ], + "title": "Single Dashboard DS Query", + "type": "stat" + }, + { + "datasource": { + "type": "mixed", + "uid": "-- Mixed --" + }, + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + } + ] + } + } + }, + "gridPos": { + "h": 3, + "w": 8, + "x": 8, + "y": 6 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.1.0-pre", + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 1, + "refId": "A", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 2, + "refId": "B", + "withTransforms": true + }, + { + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "panelId": 3, + "refId": "C", + "withTransforms": true + } + ], + "title": "Multiple Dashboard DS Queries", + "type": "stat" } ], "preload": false, diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v2alpha1.json index bb70e99ec48..d3ca201e380 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v2alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.ds-data-query.v2alpha1.json @@ -852,6 +852,194 @@ } } } + }, + "panel-7": { + "kind": "Panel", + "spec": { + "id": 7, + "title": "Single Dashboard DS Query", + "description": "Panel with a single -- Dashboard -- datasource query", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "12.1.0-pre", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } + }, + "panel-8": { + "kind": "Panel", + "spec": { + "id": 8, + "title": "Multiple Dashboard DS Queries", + "description": "Panel with multiple -- Dashboard -- datasource queries (should be mixed)", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 1, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 2, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "B", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "datasource", + "spec": { + "panelId": 3, + "withTransforms": true + } + }, + "datasource": { + "type": "datasource", + "uid": "-- Dashboard --" + }, + "refId": "C", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "12.1.0-pre", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + } + ] + }, + "color": { + "mode": "thresholds" + } + }, + "overrides": [] + } + } + } + } } }, "layout": { @@ -946,6 +1134,32 @@ "name": "panel-6" } } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 6, + "width": 8, + "height": 3, + "element": { + "kind": "ElementReference", + "name": "panel-7" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 8, + "y": 6, + "width": 8, + "height": 3, + "element": { + "kind": "ElementReference", + "name": "panel-8" + } + } } ] } diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v0alpha1.json index f81abd723dc..bd7c8c392ee 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v0alpha1.json @@ -67,6 +67,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -219,6 +223,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -309,6 +317,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v1beta1.json index 2ade48c620d..a81de0ed319 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.rows-with-nested-tabs.v1beta1.json @@ -67,6 +67,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -219,6 +223,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -309,6 +317,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v0alpha1.json new file mode 100644 index 00000000000..98791135a12 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v0alpha1.json @@ -0,0 +1,515 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "adt885j", + "namespace": "default", + "uid": "yTWet6JgBjlRIWnqRE9ZOmUycfT0tEkr2mljaln1GWIX", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-12-16T10:44:31Z", + "labels": { + "grafana.app/deprecatedInternalID": "2409" + }, + "annotations": { + "grafana.app/createdBy": "user:u000000001", + "grafana.app/updatedBy": "user:u000000001", + "grafana.app/updatedTimestamp": "2025-12-16T10:51:14Z" + } + }, + "spec": { + "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" + } + ] + }, + "description": "", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": -1, + "panels": [], + "title": "Tab1", + "type": "row" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 0, + "y": 1 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A" + } + ], + "title": "Panel1", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 7, + "y": 1 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel2", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 9, + "x": 15, + "y": 1 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel3", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel4", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel5", + "type": "timeseries" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 42, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "browser", + "title": "Dashboard with tabs" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v2beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v1beta1.json new file mode 100644 index 00000000000..38c93eb1cc8 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v1beta1.json @@ -0,0 +1,515 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v1beta1", + "metadata": { + "name": "adt885j", + "namespace": "default", + "uid": "yTWet6JgBjlRIWnqRE9ZOmUycfT0tEkr2mljaln1GWIX", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-12-16T10:44:31Z", + "labels": { + "grafana.app/deprecatedInternalID": "2409" + }, + "annotations": { + "grafana.app/createdBy": "user:u000000001", + "grafana.app/updatedBy": "user:u000000001", + "grafana.app/updatedTimestamp": "2025-12-16T10:51:14Z" + } + }, + "spec": { + "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" + } + ] + }, + "description": "", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "liveNow": false, + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": -1, + "panels": [], + "title": "Tab1", + "type": "row" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 7, + "x": 0, + "y": 1 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A" + } + ], + "title": "Panel1", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 8, + "x": 7, + "y": 1 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel2", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 9, + "x": 15, + "y": 1 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel3", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel4", + "type": "timeseries" + }, + { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "12.4.0-pre", + "targets": [ + { + "refId": "A" + } + ], + "title": "Panel5", + "type": "timeseries" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 42, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "browser", + "title": "Dashboard with tabs" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v2beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v2alpha1.json new file mode 100644 index 00000000000..b7739508c2d --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tab-with-multiple-panels.v2alpha1.json @@ -0,0 +1,683 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "adt885j", + "namespace": "default", + "uid": "yTWet6JgBjlRIWnqRE9ZOmUycfT0tEkr2mljaln1GWIX", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-12-16T10:44:31Z", + "labels": { + "grafana.app/deprecatedInternalID": "2409" + }, + "annotations": { + "grafana.app/createdBy": "user:u000000001", + "grafana.app/updatedBy": "user:u000000001", + "grafana.app/updatedTimestamp": "2025-12-16T10:51:14Z" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "query": { + "kind": "grafana", + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true + } + } + ], + "cursorSync": "Off", + "description": "", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "Panel1", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "grafana-testdata-datasource", + "spec": {} + }, + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "12.4.0-pre", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "Panel2", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "12.4.0-pre", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "Panel3", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "12.4.0-pre", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "Panel4", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "12.4.0-pre", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Panel5", + "description": "", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "", + "spec": {} + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "timeseries", + "spec": { + "pluginVersion": "12.4.0-pre", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + }, + "fieldConfig": { + "defaults": { + "thresholds": { + "mode": "absolute", + "steps": [ + { + "value": 0, + "color": "green" + }, + { + "value": 80, + "color": "red" + } + ] + }, + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + } + }, + "overrides": [] + } + } + } + } + } + }, + "layout": { + "kind": "TabsLayout", + "spec": { + "tabs": [ + { + "kind": "TabsLayoutTab", + "spec": { + "title": "Tab1", + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 7, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 7, + "y": 0, + "width": 8, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 15, + "y": 0, + "width": 9, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + } + ] + } + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Dashboard with tabs", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v2beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v0alpha1.json index ef513d48d97..716b476f825 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v0alpha1.json @@ -54,6 +54,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -167,6 +171,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -271,6 +279,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -361,6 +373,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -467,6 +483,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v1beta1.json index f94a49fc420..f915142fd14 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-and-rows-repeated.v1beta1.json @@ -54,6 +54,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -167,6 +171,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -271,6 +279,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -361,6 +373,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -467,6 +483,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v0alpha1.json index 6ed7076e121..ebc40675495 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v0alpha1.json @@ -54,6 +54,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -167,6 +171,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -271,6 +279,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -361,6 +373,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v1beta1.json index 9444d6b8eef..b5c74ce6a26 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.tabs-with-nested-rows.v1beta1.json @@ -54,6 +54,10 @@ "type": "row" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -167,6 +171,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -271,6 +279,10 @@ "id": -1, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { @@ -361,6 +373,10 @@ "type": "timeseries" }, { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "defin43am9o1sd" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v0alpha1.json new file mode 100644 index 00000000000..916f2442b71 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v0alpha1.json @@ -0,0 +1,664 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v0alpha1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + } + }, + "spec": { + "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" + } + ] + }, + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "critical": { + "color": "red", + "index": 0, + "text": "Critical!" + }, + "ok": { + "color": "green", + "index": 2, + "text": "OK" + }, + "warning": { + "color": "orange", + "index": 1, + "text": "Warning" + } + }, + "type": "value" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "up", + "refId": "A" + } + ], + "title": "ValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 0, + "text": "Low" + }, + "to": 50 + }, + "type": "range" + }, + { + "options": { + "from": 50, + "result": { + "color": "orange", + "index": 1, + "text": "Medium" + }, + "to": 80 + }, + "type": "range" + }, + { + "options": { + "from": 80, + "result": { + "color": "red", + "index": 2, + "text": "High" + }, + "to": 100 + }, + "type": "range" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "cpu_usage_percent", + "refId": "A" + } + ], + "title": "RangeMap Example", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "pattern": "/^error.*/", + "result": { + "color": "red", + "index": 0, + "text": "Error" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^warn.*/", + "result": { + "color": "orange", + "index": 1, + "text": "Warning" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^info.*/", + "result": { + "color": "blue", + "index": 2, + "text": "Info" + } + }, + "type": "regex" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "log_level", + "refId": "A" + } + ], + "title": "RegexMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 0, + "text": "No Data" + } + }, + "type": "special" + }, + { + "options": { + "match": "nan", + "result": { + "color": "gray", + "index": 1, + "text": "Not a Number" + } + }, + "type": "special" + }, + { + "options": { + "match": "null+nan", + "result": { + "color": "gray", + "index": 2, + "text": "N/A" + } + }, + "type": "special" + }, + { + "options": { + "match": "true", + "result": { + "color": "green", + "index": 3, + "text": "Yes" + } + }, + "type": "special" + }, + { + "options": { + "match": "false", + "result": { + "color": "red", + "index": 4, + "text": "No" + } + }, + "type": "special" + }, + { + "options": { + "match": "empty", + "result": { + "color": "gray", + "index": 5, + "text": "Empty" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "some_metric", + "refId": "A" + } + ], + "title": "SpecialValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "failure": { + "color": "red", + "index": 1, + "text": "Failure" + }, + "success": { + "color": "green", + "index": 0, + "text": "Success" + } + }, + "type": "value" + }, + { + "options": { + "from": 0, + "result": { + "color": "blue", + "index": 2, + "text": "In Range" + }, + "to": 100 + }, + "type": "range" + }, + { + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "color": "purple", + "index": 3, + "text": "ID Format" + } + }, + "type": "regex" + }, + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 4, + "text": "Missing" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 5, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "combined_metric", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "secondary_metric", + "refId": "B" + } + ], + "title": "Combined Mappings and Overrides Example", + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with override that has empty properties array - tests conversion of overrides without any property modifications", + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "field_with_empty_override" + }, + "properties": [] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 6, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "empty_override_metric", + "refId": "A" + } + ], + "title": "Empty Properties Override Example", + "type": "stat" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 42, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "browser", + "title": "Value Mapping and Overrides Test" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v2beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v1beta1.json new file mode 100644 index 00000000000..9c96e15fbc3 --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v1beta1.json @@ -0,0 +1,664 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v1beta1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + } + }, + "spec": { + "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" + } + ] + }, + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "critical": { + "color": "red", + "index": 0, + "text": "Critical!" + }, + "ok": { + "color": "green", + "index": 2, + "text": "OK" + }, + "warning": { + "color": "orange", + "index": 1, + "text": "Warning" + } + }, + "type": "value" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "up", + "refId": "A" + } + ], + "title": "ValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "from": 0, + "result": { + "color": "green", + "index": 0, + "text": "Low" + }, + "to": 50 + }, + "type": "range" + }, + { + "options": { + "from": 50, + "result": { + "color": "orange", + "index": 1, + "text": "Medium" + }, + "to": 80 + }, + "type": "range" + }, + { + "options": { + "from": 80, + "result": { + "color": "red", + "index": 2, + "text": "High" + }, + "to": 100 + }, + "type": "range" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "cpu_usage_percent", + "refId": "A" + } + ], + "title": "RangeMap Example", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "pattern": "/^error.*/", + "result": { + "color": "red", + "index": 0, + "text": "Error" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^warn.*/", + "result": { + "color": "orange", + "index": 1, + "text": "Warning" + } + }, + "type": "regex" + }, + { + "options": { + "pattern": "/^info.*/", + "result": { + "color": "blue", + "index": 2, + "text": "Info" + } + }, + "type": "regex" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "log_level", + "refId": "A" + } + ], + "title": "RegexMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 0, + "text": "No Data" + } + }, + "type": "special" + }, + { + "options": { + "match": "nan", + "result": { + "color": "gray", + "index": 1, + "text": "Not a Number" + } + }, + "type": "special" + }, + { + "options": { + "match": "null+nan", + "result": { + "color": "gray", + "index": 2, + "text": "N/A" + } + }, + "type": "special" + }, + { + "options": { + "match": "true", + "result": { + "color": "green", + "index": 3, + "text": "Yes" + } + }, + "type": "special" + }, + { + "options": { + "match": "false", + "result": { + "color": "red", + "index": 4, + "text": "No" + } + }, + "type": "special" + }, + { + "options": { + "match": "empty", + "result": { + "color": "gray", + "index": 5, + "text": "Empty" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "some_metric", + "refId": "A" + } + ], + "title": "SpecialValueMap Example", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "failure": { + "color": "red", + "index": 1, + "text": "Failure" + }, + "success": { + "color": "green", + "index": 0, + "text": "Success" + } + }, + "type": "value" + }, + { + "options": { + "from": 0, + "result": { + "color": "blue", + "index": 2, + "text": "In Range" + }, + "to": 100 + }, + "type": "range" + }, + { + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "color": "purple", + "index": 3, + "text": "ID Format" + } + }, + "type": "regex" + }, + { + "options": { + "match": "null", + "result": { + "color": "gray", + "index": 4, + "text": "Missing" + } + }, + "type": "special" + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 5, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "combined_metric", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "secondary_metric", + "refId": "B" + } + ], + "title": "Combined Mappings and Overrides Example", + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "description": "Panel with override that has empty properties array - tests conversion of overrides without any property modifications", + "fieldConfig": { + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "field_with_empty_override" + }, + "properties": [] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 6, + "options": {}, + "pluginVersion": "", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "expr": "empty_override_metric", + "refId": "A" + } + ], + "title": "Empty Properties Override Example", + "type": "stat" + } + ], + "preload": false, + "refresh": "", + "schemaVersion": 42, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "browser", + "title": "Value Mapping and Overrides Test" + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v2beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v2alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v2alpha1.json new file mode 100644 index 00000000000..425b914eafb --- /dev/null +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.value-mapping-and-overrides.v2alpha1.json @@ -0,0 +1,850 @@ +{ + "kind": "DashboardWithAccessInfo", + "apiVersion": "dashboard.grafana.app/v2alpha1", + "metadata": { + "name": "value-mapping-test", + "namespace": "default", + "uid": "value-mapping-test", + "resourceVersion": "1765384157199094", + "generation": 2, + "creationTimestamp": "2025-11-19T20:09:28Z", + "labels": { + "grafana.app/deprecatedInternalID": "646372978987008" + } + }, + "spec": { + "annotations": [ + { + "kind": "AnnotationQuery", + "spec": { + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "query": { + "kind": "grafana", + "spec": {} + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations \u0026 Alerts", + "builtIn": true, + "legacyOptions": { + "type": "dashboard" + } + } + } + ], + "cursorSync": "Off", + "description": "Test dashboard for all value mapping types and override matcher types", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "id": 1, + "title": "ValueMap Example", + "description": "Panel with ValueMap mapping type - maps specific text values to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "up" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "critical": { + "text": "Critical!", + "color": "red", + "index": 0 + }, + "ok": { + "text": "OK", + "color": "green", + "index": 2 + }, + "warning": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 100 + }, + { + "id": "custom.align", + "value": "center" + } + ] + } + ] + } + } + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "id": 2, + "title": "RangeMap Example", + "description": "Panel with RangeMap mapping type - maps numerical ranges to colors and display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "cpu_usage_percent" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "gauge", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "range", + "options": { + "from": 0, + "to": 50, + "result": { + "text": "Low", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 50, + "to": 80, + "result": { + "text": "Medium", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "range", + "options": { + "from": 80, + "to": 100, + "result": { + "text": "High", + "color": "red", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/^cpu_/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "decimals", + "value": 2 + } + ] + } + ] + } + } + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "id": 3, + "title": "RegexMap Example", + "description": "Panel with RegexMap mapping type - maps values matching regex patterns to colors", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "log_level" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "regex", + "options": { + "pattern": "/^error.*/", + "result": { + "text": "Error", + "color": "red", + "index": 0 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^warn.*/", + "result": { + "text": "Warning", + "color": "orange", + "index": 1 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^info.*/", + "result": { + "text": "Info", + "color": "blue", + "index": 2 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byType", + "options": "string" + }, + "properties": [ + { + "id": "custom.cellOptions", + "value": { + "type": "color-text" + } + } + ] + } + ] + } + } + } + } + }, + "panel-4": { + "kind": "Panel", + "spec": { + "id": 4, + "title": "SpecialValueMap Example", + "description": "Panel with SpecialValueMap mapping type - maps special values like null, NaN, true, false to display text", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "some_metric" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "No Data", + "color": "gray", + "index": 0 + } + } + }, + { + "type": "special", + "options": { + "match": "nan", + "result": { + "text": "Not a Number", + "color": "gray", + "index": 1 + } + } + }, + { + "type": "special", + "options": { + "match": "null+nan", + "result": { + "text": "N/A", + "color": "gray", + "index": 2 + } + } + }, + { + "type": "special", + "options": { + "match": "true", + "result": { + "text": "Yes", + "color": "green", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "false", + "result": { + "text": "No", + "color": "red", + "index": 4 + } + } + }, + { + "type": "special", + "options": { + "match": "empty", + "result": { + "text": "Empty", + "color": "gray", + "index": 5 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byFrameRefID", + "options": "A" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "blue", + "mode": "fixed" + } + } + ] + } + ] + } + } + } + } + }, + "panel-5": { + "kind": "Panel", + "spec": { + "id": 5, + "title": "Combined Mappings and Overrides Example", + "description": "Panel with all mapping types combined - demonstrates mixing different mapping types and multiple override matchers", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "combined_metric" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + }, + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "secondary_metric" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "B", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "table", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "type": "value", + "options": { + "failure": { + "text": "Failure", + "color": "red", + "index": 1 + }, + "success": { + "text": "Success", + "color": "green", + "index": 0 + } + } + }, + { + "type": "range", + "options": { + "from": 0, + "to": 100, + "result": { + "text": "In Range", + "color": "blue", + "index": 2 + } + } + }, + { + "type": "regex", + "options": { + "pattern": "/^[A-Z]{3}-\\d+$/", + "result": { + "text": "ID Format", + "color": "purple", + "index": 3 + } + } + }, + { + "type": "special", + "options": { + "match": "null", + "result": { + "text": "Missing", + "color": "gray", + "index": 4 + } + } + } + ] + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "status" + }, + "properties": [ + { + "id": "custom.width", + "value": 120 + }, + { + "id": "custom.cellOptions", + "value": { + "type": "color-background" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": "/^value_/" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "min", + "value": 0 + }, + { + "id": "max", + "value": 100 + } + ] + }, + { + "matcher": { + "id": "byType", + "options": "number" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "red", + "value": 80 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byFrameRefID", + "options": "B" + }, + "properties": [ + { + "id": "displayName", + "value": "Secondary Query" + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hidden", + "value": true + } + ] + } + ] + } + } + } + } + }, + "panel-6": { + "kind": "Panel", + "spec": { + "id": 6, + "title": "Empty Properties Override Example", + "description": "Panel with override that has empty properties array - tests conversion of overrides without any property modifications", + "links": [], + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "query": { + "kind": "prometheus", + "spec": { + "expr": "empty_override_metric" + } + }, + "datasource": { + "type": "prometheus", + "uid": "prometheus-uid" + }, + "refId": "A", + "hidden": false + } + } + ], + "transformations": [], + "queryOptions": {} + } + }, + "vizConfig": { + "kind": "stat", + "spec": { + "pluginVersion": "", + "options": {}, + "fieldConfig": { + "defaults": {}, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "field_with_empty_override" + }, + "properties": [] + } + ] + } + } + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-1" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 0, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-2" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-3" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 12, + "y": 8, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-4" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 16, + "width": 24, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-5" + } + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "x": 0, + "y": 24, + "width": 12, + "height": 8, + "element": { + "kind": "ElementReference", + "name": "panel-6" + } + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [ + "value-mapping", + "overrides", + "test" + ], + "timeSettings": { + "timezone": "browser", + "from": "now-6h", + "to": "now", + "autoRefresh": "", + "autoRefreshIntervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "hideTimepicker": false, + "fiscalYearStartMonth": 0 + }, + "title": "Value Mapping and Overrides Test", + "variables": [] + }, + "status": { + "conversion": { + "failed": false, + "storedVersion": "v2beta1" + } + } +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v0alpha1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v0alpha1.json index 0502ebf6b4c..083dfb5347c 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v0alpha1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v0alpha1.json @@ -14,6 +14,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v1beta1.json b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v1beta1.json index 2187a3406e7..69cec2d4e7b 100644 --- a/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v1beta1.json +++ b/apps/dashboard/pkg/migration/conversion/testdata/output/v2beta1.viz-config.v1beta1.json @@ -14,6 +14,10 @@ "liveNow": false, "panels": [ { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "gdev-testdata" + }, "fieldConfig": { "defaults": { "color": { diff --git a/apps/dashboard/pkg/migration/conversion/v0.go b/apps/dashboard/pkg/migration/conversion/v0.go index 826293d9564..513f6975516 100644 --- a/apps/dashboard/pkg/migration/conversion/v0.go +++ b/apps/dashboard/pkg/migration/conversion/v0.go @@ -13,6 +13,9 @@ import ( func Convert_V0_to_V1beta1(in *dashv0.Dashboard, out *dashv1.Dashboard, scope conversion.Scope) error { if err := ConvertDashboard_V0_to_V1beta1(in, out, scope); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv1.APIVERSION + out.Kind = in.Kind out.Status = dashv1.DashboardStatus{ Conversion: &dashv1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv0.VERSION), @@ -22,12 +25,24 @@ func Convert_V0_to_V1beta1(in *dashv0.Dashboard, out *dashv1.Dashboard, scope co } return err } + + // Set successful conversion status + out.Status = dashv1.DashboardStatus{ + Conversion: &dashv1.DashboardConversionStatus{ + StoredVersion: ptr.To(dashv0.VERSION), + Failed: false, + }, + } + return nil } func Convert_V0_to_V2alpha1(in *dashv0.Dashboard, out *dashv2alpha1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) error { v1beta1 := &dashv1.Dashboard{} if err := ConvertDashboard_V0_to_V1beta1(in, v1beta1, scope); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2alpha1.APIVERSION + out.Kind = in.Kind out.Status = dashv2alpha1.DashboardStatus{ Conversion: &dashv2alpha1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv0.VERSION), @@ -35,7 +50,6 @@ func Convert_V0_to_V2alpha1(in *dashv0.Dashboard, out *dashv2alpha1.Dashboard, s Error: ptr.To(err.Error()), }, } - // Don't return error - just set status (matches test expectations) // Ensure layout is set even on error to prevent JSON marshaling issues if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { out.Spec.Layout = dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ @@ -45,10 +59,13 @@ func Convert_V0_to_V2alpha1(in *dashv0.Dashboard, out *dashv2alpha1.Dashboard, s }, } } - return nil + return err } if err := ConvertDashboard_V1beta1_to_V2alpha1(v1beta1, out, scope, dsIndexProvider, leIndexProvider); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2alpha1.APIVERSION + out.Kind = in.Kind out.Status = dashv2alpha1.DashboardStatus{ Conversion: &dashv2alpha1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv0.VERSION), @@ -56,7 +73,6 @@ func Convert_V0_to_V2alpha1(in *dashv0.Dashboard, out *dashv2alpha1.Dashboard, s Error: ptr.To(err.Error()), }, } - // Don't return error - just set status (matches test expectations) // Ensure layout is set even on error to prevent JSON marshaling issues if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { out.Spec.Layout = dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ @@ -66,7 +82,15 @@ func Convert_V0_to_V2alpha1(in *dashv0.Dashboard, out *dashv2alpha1.Dashboard, s }, } } - return nil + return err + } + + // Set successful conversion status + out.Status = dashv2alpha1.DashboardStatus{ + Conversion: &dashv2alpha1.DashboardConversionStatus{ + StoredVersion: ptr.To(dashv0.VERSION), + Failed: false, + }, } return nil @@ -75,6 +99,9 @@ func Convert_V0_to_V2alpha1(in *dashv0.Dashboard, out *dashv2alpha1.Dashboard, s func Convert_V0_to_V2beta1(in *dashv0.Dashboard, out *dashv2beta1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) error { v1beta1 := &dashv1.Dashboard{} if err := ConvertDashboard_V0_to_V1beta1(in, v1beta1, scope); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2beta1.APIVERSION + out.Kind = in.Kind out.Status = dashv2beta1.DashboardStatus{ Conversion: &dashv2beta1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv0.VERSION), @@ -82,11 +109,23 @@ func Convert_V0_to_V2beta1(in *dashv0.Dashboard, out *dashv2beta1.Dashboard, sco Error: ptr.To(err.Error()), }, } + // Ensure layout is set even on error to prevent JSON marshaling issues + if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { + out.Spec.Layout = dashv2beta1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2beta1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2beta1.DashboardGridLayoutSpec{}, + }, + } + } return err } v2alpha1 := &dashv2alpha1.Dashboard{} if err := ConvertDashboard_V1beta1_to_V2alpha1(v1beta1, v2alpha1, scope, dsIndexProvider, leIndexProvider); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2beta1.APIVERSION + out.Kind = in.Kind out.Status = dashv2beta1.DashboardStatus{ Conversion: &dashv2beta1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv0.VERSION), @@ -94,10 +133,22 @@ func Convert_V0_to_V2beta1(in *dashv0.Dashboard, out *dashv2beta1.Dashboard, sco Error: ptr.To(err.Error()), }, } + // Ensure layout is set even on error to prevent JSON marshaling issues + if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { + out.Spec.Layout = dashv2beta1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2beta1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2beta1.DashboardGridLayoutSpec{}, + }, + } + } return err } if err := ConvertDashboard_V2alpha1_to_V2beta1(v2alpha1, out, scope); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2beta1.APIVERSION + out.Kind = in.Kind out.Status = dashv2beta1.DashboardStatus{ Conversion: &dashv2beta1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv0.VERSION), @@ -105,8 +156,25 @@ func Convert_V0_to_V2beta1(in *dashv0.Dashboard, out *dashv2beta1.Dashboard, sco Error: ptr.To(err.Error()), }, } + // Ensure layout is set even on error to prevent JSON marshaling issues + if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { + out.Spec.Layout = dashv2beta1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2beta1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2beta1.DashboardGridLayoutSpec{}, + }, + } + } return err } + // Set successful conversion status + out.Status = dashv2beta1.DashboardStatus{ + Conversion: &dashv2beta1.DashboardConversionStatus{ + StoredVersion: ptr.To(dashv0.VERSION), + Failed: false, + }, + } + return nil } diff --git a/apps/dashboard/pkg/migration/conversion/v0_test.go b/apps/dashboard/pkg/migration/conversion/v0_test.go index ca2210f01e8..3620ea4d099 100644 --- a/apps/dashboard/pkg/migration/conversion/v0_test.go +++ b/apps/dashboard/pkg/migration/conversion/v0_test.go @@ -20,7 +20,7 @@ func TestV0ConversionErrorHandling(t *testing.T) { // Initialize the migrator with a test data source provider dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) tests := []struct { name string @@ -54,7 +54,7 @@ func TestV0ConversionErrorHandling(t *testing.T) { }, }, { - name: "Convert_V0_to_V2alpha1 sets status on first step migration failure", + name: "Convert_V0_to_V2alpha1 returns error and sets status on first step migration failure", source: &dashv0.Dashboard{ ObjectMeta: metav1.ObjectMeta{ Namespace: "org-1", @@ -67,7 +67,7 @@ func TestV0ConversionErrorHandling(t *testing.T) { }, }, target: &dashv2alpha1.Dashboard{}, - expectError: false, // Convert_V0_to_V2alpha1 doesn't return error, just sets status + expectError: true, // Convert_V0_to_V2alpha1 now returns error for proper metrics/logging expectStatusSet: true, checkStatus: func(t *testing.T, target interface{}) { out := target.(*dashv2alpha1.Dashboard) @@ -132,7 +132,7 @@ func TestV0ConversionErrorPropagation(t *testing.T) { // Initialize the migrator with a test data source provider dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) t.Run("ConvertDashboard_V0_to_V1beta1 returns error on migration failure", func(t *testing.T) { source := &dashv0.Dashboard{ @@ -206,7 +206,7 @@ func TestV0ConversionSuccessPaths(t *testing.T) { // Initialize the migrator with a test data source provider dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) t.Run("Convert_V0_to_V1beta1 success path returns nil", func(t *testing.T) { source := &dashv0.Dashboard{ @@ -275,9 +275,9 @@ func TestV0ConversionSecondStepErrors(t *testing.T) { // Initialize the migrator with a test data source provider dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) - t.Run("Convert_V0_to_V2alpha1 sets status on first step error", func(t *testing.T) { + t.Run("Convert_V0_to_V2alpha1 returns error and sets status on first step error", func(t *testing.T) { // Create a dashboard that will fail v0->v1beta1 conversion // Use schemaVersion 0 which will cause migration to fail source := &dashv0.Dashboard{ @@ -295,16 +295,16 @@ func TestV0ConversionSecondStepErrors(t *testing.T) { err := Convert_V0_to_V2alpha1(source, target, nil, dsProvider, leProvider) - // Convert_V0_to_V2alpha1 doesn't return error, just sets status - require.NoError(t, err, "Convert_V0_to_V2alpha1 doesn't return error") - // Status should be set when first step fails + // Convert_V0_to_V2alpha1 returns error for proper metrics/logging + require.Error(t, err, "Convert_V0_to_V2alpha1 should return error") + // Status should also be set when first step fails require.NotNil(t, target.Status.Conversion, "Status should be set on first step error") require.True(t, target.Status.Conversion.Failed, "Failed should be true") require.NotNil(t, target.Status.Conversion.Error, "Error should be set") require.Equal(t, dashv0.VERSION, *target.Status.Conversion.StoredVersion) }) - t.Run("Convert_V0_to_V2alpha1 sets status on second step error", func(t *testing.T) { + t.Run("Convert_V0_to_V2alpha1 returns error and sets status on second step error", func(t *testing.T) { // Create a dashboard that will pass v0->v1beta1 but fail v1beta1->v2alpha1 // We need to create invalid JSON structure that will cause JSON marshaling to fail // or create a dashboard with invalid structure that causes transformation to fail @@ -329,16 +329,13 @@ func TestV0ConversionSecondStepErrors(t *testing.T) { err := Convert_V0_to_V2alpha1(source, target, nil, dsProvider, leProvider) - // Convert_V0_to_V2alpha1 doesn't return error, just sets status - require.NoError(t, err, "Convert_V0_to_V2alpha1 doesn't return error") - // If second step fails, status should be set - // Note: The error might occur in first step if JSON marshal fails early, - // but we're testing that the error handling path exists - if target.Status.Conversion != nil && target.Status.Conversion.Failed { - require.True(t, target.Status.Conversion.Failed) - require.NotNil(t, target.Status.Conversion.Error) - require.Equal(t, dashv0.VERSION, *target.Status.Conversion.StoredVersion) - } + // Convert_V0_to_V2alpha1 returns error for proper metrics/logging + require.Error(t, err, "Convert_V0_to_V2alpha1 should return error") + // Status should also be set + require.NotNil(t, target.Status.Conversion, "Status should be set on error") + require.True(t, target.Status.Conversion.Failed, "Failed should be true") + require.NotNil(t, target.Status.Conversion.Error, "Error should be set") + require.Equal(t, dashv0.VERSION, *target.Status.Conversion.StoredVersion) }) t.Run("Convert_V0_to_V2beta1 returns error on second step failure", func(t *testing.T) { @@ -394,3 +391,177 @@ func TestV0ConversionSecondStepErrors(t *testing.T) { } }) } + +// TestV0ConversionConsistency_ErrorsMustBeReturned ensures v0 conversion functions +// return errors instead of swallowing them. This prevents metrics and logs from being silently dropped. +func TestV0ConversionConsistency_ErrorsMustBeReturned(t *testing.T) { + dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) + leProvider := migrationtestutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + // Create a v0 dashboard that will fail conversion (invalid schema version) + invalidV0 := &dashv0.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "org-1", + Name: "test-dashboard", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 0, // Invalid schema version causes migration to fail + }, + }, + } + + t.Run("Convert_V0_to_V1beta1 must return error on failure", func(t *testing.T) { + target := &dashv1.Dashboard{} + err := Convert_V0_to_V1beta1(invalidV0, target, nil) + require.Error(t, err, "Convert_V0_to_V1beta1 must return error, not swallow it") + require.True(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be true") + }) + + t.Run("Convert_V0_to_V2alpha1 must return error on failure", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + err := Convert_V0_to_V2alpha1(invalidV0, target, nil, dsProvider, leProvider) + require.Error(t, err, "Convert_V0_to_V2alpha1 must return error, not swallow it") + require.True(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be true") + }) + + t.Run("Convert_V0_to_V2beta1 must return error on failure", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + err := Convert_V0_to_V2beta1(invalidV0, target, nil, dsProvider, leProvider) + require.Error(t, err, "Convert_V0_to_V2beta1 must return error, not swallow it") + require.True(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be true") + }) +} + +// TestV0ConversionConsistency_SuccessStatusMustBeSet ensures v0 conversion functions +// set Status.Conversion with Failed=false on successful conversion. +func TestV0ConversionConsistency_SuccessStatusMustBeSet(t *testing.T) { + dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) + leProvider := migrationtestutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + // Create a valid v0 dashboard + validV0 := &dashv0.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test-dashboard", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 42, + }, + }, + } + + t.Run("Convert_V0_to_V1beta1 must set success status", func(t *testing.T) { + target := &dashv1.Dashboard{} + err := Convert_V0_to_V1beta1(validV0, target, nil) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + require.Equal(t, dashv0.VERSION, *target.Status.Conversion.StoredVersion) + }) + + t.Run("Convert_V0_to_V2alpha1 must set success status", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + err := Convert_V0_to_V2alpha1(validV0, target, nil, dsProvider, leProvider) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + require.Equal(t, dashv0.VERSION, *target.Status.Conversion.StoredVersion) + }) + + t.Run("Convert_V0_to_V2beta1 must set success status", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + err := Convert_V0_to_V2beta1(validV0, target, nil, dsProvider, leProvider) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + require.Equal(t, dashv0.VERSION, *target.Status.Conversion.StoredVersion) + }) +} + +// TestV0ConversionConsistency_ObjectMetaMustBeSetOnError ensures v0 conversion functions +// set ObjectMeta, APIVersion, and Kind on the target even when conversion fails. +func TestV0ConversionConsistency_ObjectMetaMustBeSetOnError(t *testing.T) { + dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) + leProvider := migrationtestutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + invalidV0 := &dashv0.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "org-1", + Name: "test-dashboard", + UID: "test-uid", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 0, + }, + }, + } + + t.Run("Convert_V0_to_V1beta1 must set ObjectMeta on error", func(t *testing.T) { + target := &dashv1.Dashboard{} + _ = Convert_V0_to_V1beta1(invalidV0, target, nil) + require.Equal(t, invalidV0.Name, target.Name, "Name must be set on error") + require.Equal(t, invalidV0.Namespace, target.Namespace, "Namespace must be set on error") + require.Equal(t, dashv1.APIVERSION, target.APIVersion, "APIVersion must be set on error") + }) + + t.Run("Convert_V0_to_V2alpha1 must set ObjectMeta on error", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + _ = Convert_V0_to_V2alpha1(invalidV0, target, nil, dsProvider, leProvider) + require.Equal(t, invalidV0.Name, target.Name, "Name must be set on error") + require.Equal(t, invalidV0.Namespace, target.Namespace, "Namespace must be set on error") + require.Equal(t, dashv2alpha1.APIVERSION, target.APIVersion, "APIVersion must be set on error") + }) + + t.Run("Convert_V0_to_V2beta1 must set ObjectMeta on error", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + _ = Convert_V0_to_V2beta1(invalidV0, target, nil, dsProvider, leProvider) + require.Equal(t, invalidV0.Name, target.Name, "Name must be set on error") + require.Equal(t, invalidV0.Namespace, target.Namespace, "Namespace must be set on error") + require.Equal(t, dashv2beta1.APIVERSION, target.APIVersion, "APIVersion must be set on error") + }) +} + +// TestV0ConversionConsistency_LayoutMustBeSetOnError ensures v2alpha1 and v2beta1 targets +// have a default layout set even when conversion fails to prevent JSON marshaling errors. +func TestV0ConversionConsistency_LayoutMustBeSetOnError(t *testing.T) { + dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) + leProvider := migrationtestutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + invalidV0 := &dashv0.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "org-1", + Name: "test-dashboard", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 0, + }, + }, + } + + t.Run("Convert_V0_to_V2alpha1 must set default layout on error", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + _ = Convert_V0_to_V2alpha1(invalidV0, target, nil, dsProvider, leProvider) + require.NotNil(t, target.Spec.Layout.GridLayoutKind, "GridLayoutKind must be set on error to prevent JSON marshaling issues") + }) + + t.Run("Convert_V0_to_V2beta1 must set default layout on error", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + _ = Convert_V0_to_V2beta1(invalidV0, target, nil, dsProvider, leProvider) + require.NotNil(t, target.Spec.Layout.GridLayoutKind, "GridLayoutKind must be set on error to prevent JSON marshaling issues") + }) +} diff --git a/apps/dashboard/pkg/migration/conversion/v0alpha1_to_v1beta1.go b/apps/dashboard/pkg/migration/conversion/v0alpha1_to_v1beta1.go index 2154a26e3a2..df2db1ac5a1 100644 --- a/apps/dashboard/pkg/migration/conversion/v0alpha1_to_v1beta1.go +++ b/apps/dashboard/pkg/migration/conversion/v0alpha1_to_v1beta1.go @@ -2,6 +2,7 @@ package conversion import ( "context" + "strings" "k8s.io/apimachinery/pkg/conversion" "k8s.io/apiserver/pkg/endpoints/request" @@ -79,5 +80,121 @@ func ConvertDashboard_V0_to_V1beta1(in *dashv0.Dashboard, out *dashv1.Dashboard, return schemaversion.NewMigrationError(err.Error(), schemaversion.GetSchemaVersion(in.Spec.Object), schemaversion.LATEST_VERSION, "Convert_V0_to_V1") } + // Normalize template variable datasources from string to object format + // This handles legacy dashboards where query variables have datasource: "$datasource" (string) + // instead of datasource: { uid: "$datasource" } (object) + // our migration pipeline in v36 doesn't address because this was not addressed historically + // in DashboardMigrator - see public/app/features/dashboard/state/DashboardMigrator.ts#L607 + // Which means that we have schemaVersion: 42 dashboards where datasource variable references are still strings + normalizeTemplateVariableDatasources(out.Spec.Object) + + // Normalize panel and target datasources from string to object format + // This handles legacy dashboards where panels/targets have datasource: "$datasource" (string) + // instead of datasource: { uid: "$datasource" } (object) + normalizePanelDatasources(out.Spec.Object) + return nil } + +// normalizeTemplateVariableDatasources converts template variable string datasources to object format. +// Legacy dashboards may have query variables with datasource: "$datasource" (string). +// This normalizes them to datasource: { uid: "$datasource" } for consistent V1→V2 conversion. +func normalizeTemplateVariableDatasources(dashboard map[string]interface{}) { + templating, ok := dashboard["templating"].(map[string]interface{}) + if !ok { + return + } + + list, ok := templating["list"].([]interface{}) + if !ok { + return + } + + for _, variable := range list { + varMap, ok := variable.(map[string]interface{}) + if !ok { + continue + } + + varType, _ := varMap["type"].(string) + if varType != "query" { + continue + } + + ds := varMap["datasource"] + if dsStr, ok := ds.(string); ok && isTemplateVariableRef(dsStr) { + // Convert string template variable reference to object format + varMap["datasource"] = map[string]interface{}{ + "uid": dsStr, + } + } + } +} + +// isTemplateVariableRef checks if a string is a Grafana template variable reference. +// Template variables can be in the form: $varname or ${varname} +func isTemplateVariableRef(s string) bool { + if s == "" { + return false + } + return strings.HasPrefix(s, "$") || strings.HasPrefix(s, "${") +} + +// normalizePanelDatasources converts panel and target string datasources to object format. +// Legacy dashboards may have panels/targets with datasource: "$datasource" (string). +// This normalizes them to datasource: { uid: "$datasource" } for consistent V1→V2 conversion. +func normalizePanelDatasources(dashboard map[string]interface{}) { + panels, ok := dashboard["panels"].([]interface{}) + if !ok { + return + } + + normalizePanelsDatasources(panels) +} + +// normalizePanelsDatasources normalizes datasources in a list of panels (including nested row panels) +func normalizePanelsDatasources(panels []interface{}) { + for _, panel := range panels { + panelMap, ok := panel.(map[string]interface{}) + if !ok { + continue + } + + // Handle row panels with nested panels + if panelType, _ := panelMap["type"].(string); panelType == "row" { + if nestedPanels, ok := panelMap["panels"].([]interface{}); ok { + normalizePanelsDatasources(nestedPanels) + } + } + + // Normalize panel-level datasource + if ds := panelMap["datasource"]; ds != nil { + if dsStr, ok := ds.(string); ok && isTemplateVariableRef(dsStr) { + panelMap["datasource"] = map[string]interface{}{ + "uid": dsStr, + } + } + } + + // Normalize target-level datasources + targets, ok := panelMap["targets"].([]interface{}) + if !ok { + continue + } + + for _, target := range targets { + targetMap, ok := target.(map[string]interface{}) + if !ok { + continue + } + + if ds := targetMap["datasource"]; ds != nil { + if dsStr, ok := ds.(string); ok && isTemplateVariableRef(dsStr) { + targetMap["datasource"] = map[string]interface{}{ + "uid": dsStr, + } + } + } + } + } +} diff --git a/apps/dashboard/pkg/migration/conversion/v1.go b/apps/dashboard/pkg/migration/conversion/v1.go index a6f2836b464..ac538e01e02 100644 --- a/apps/dashboard/pkg/migration/conversion/v1.go +++ b/apps/dashboard/pkg/migration/conversion/v1.go @@ -29,6 +29,9 @@ func Convert_V1beta1_to_V0(in *dashv1.Dashboard, out *dashv0.Dashboard, scope co func Convert_V1beta1_to_V2alpha1(in *dashv1.Dashboard, out *dashv2alpha1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) error { if err := ConvertDashboard_V1beta1_to_V2alpha1(in, out, scope, dsIndexProvider, leIndexProvider); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2alpha1.APIVERSION + out.Kind = in.Kind out.Status = dashv2alpha1.DashboardStatus{ Conversion: &dashv2alpha1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv1.VERSION), @@ -36,7 +39,6 @@ func Convert_V1beta1_to_V2alpha1(in *dashv1.Dashboard, out *dashv2alpha1.Dashboa Error: ptr.To(err.Error()), }, } - // Don't return error - just set status (matches test expectations and V0 pattern for Convert_V0_to_V2alpha1) // Ensure layout is set even on error to prevent JSON marshaling issues if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { out.Spec.Layout = dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ @@ -46,7 +48,7 @@ func Convert_V1beta1_to_V2alpha1(in *dashv1.Dashboard, out *dashv2alpha1.Dashboa }, } } - return nil + return err } // We need to make sure the layout is set to some value, otherwise the JSON marshaling will fail. @@ -59,12 +61,23 @@ func Convert_V1beta1_to_V2alpha1(in *dashv1.Dashboard, out *dashv2alpha1.Dashboa } } + // Set successful conversion status + out.Status = dashv2alpha1.DashboardStatus{ + Conversion: &dashv2alpha1.DashboardConversionStatus{ + StoredVersion: ptr.To(dashv1.VERSION), + Failed: false, + }, + } + return nil } func Convert_V1beta1_to_V2beta1(in *dashv1.Dashboard, out *dashv2beta1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) error { v2alpha1 := &dashv2alpha1.Dashboard{} if err := ConvertDashboard_V1beta1_to_V2alpha1(in, v2alpha1, scope, dsIndexProvider, leIndexProvider); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2beta1.APIVERSION + out.Kind = in.Kind out.Status = dashv2beta1.DashboardStatus{ Conversion: &dashv2beta1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv1.VERSION), @@ -72,10 +85,22 @@ func Convert_V1beta1_to_V2beta1(in *dashv1.Dashboard, out *dashv2beta1.Dashboard Error: ptr.To(err.Error()), }, } + // Ensure layout is set even on error to prevent JSON marshaling issues + if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { + out.Spec.Layout = dashv2beta1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2beta1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2beta1.DashboardGridLayoutSpec{}, + }, + } + } return err } if err := ConvertDashboard_V2alpha1_to_V2beta1(v2alpha1, out, scope); err != nil { + out.ObjectMeta = in.ObjectMeta + out.APIVersion = dashv2beta1.APIVERSION + out.Kind = in.Kind out.Status = dashv2beta1.DashboardStatus{ Conversion: &dashv2beta1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv1.VERSION), @@ -83,8 +108,25 @@ func Convert_V1beta1_to_V2beta1(in *dashv1.Dashboard, out *dashv2beta1.Dashboard Error: ptr.To(err.Error()), }, } + // Ensure layout is set even on error to prevent JSON marshaling issues + if out.Spec.Layout.GridLayoutKind == nil && out.Spec.Layout.RowsLayoutKind == nil { + out.Spec.Layout = dashv2beta1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2beta1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2beta1.DashboardGridLayoutSpec{}, + }, + } + } return err } + // Set successful conversion status + out.Status = dashv2beta1.DashboardStatus{ + Conversion: &dashv2beta1.DashboardConversionStatus{ + StoredVersion: ptr.To(dashv1.VERSION), + Failed: false, + }, + } + return nil } diff --git a/apps/dashboard/pkg/migration/conversion/v1_test.go b/apps/dashboard/pkg/migration/conversion/v1_test.go index 4525e974e01..6eca186d3ee 100644 --- a/apps/dashboard/pkg/migration/conversion/v1_test.go +++ b/apps/dashboard/pkg/migration/conversion/v1_test.go @@ -19,11 +19,10 @@ func TestV1ConversionErrorHandling(t *testing.T) { // Initialize the migrator with a test data source provider dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) - t.Run("Convert_V1beta1_to_V2alpha1 sets status on conversion error", func(t *testing.T) { - // Create a dashboard that will cause conversion to fail - // We can use an invalid dashboard structure + t.Run("Convert_V1beta1_to_V2alpha1 sets status on successful conversion", func(t *testing.T) { + // Create a simple dashboard that will convert successfully source := &dashv1.Dashboard{ ObjectMeta: metav1.ObjectMeta{ Namespace: "org-1", @@ -31,7 +30,6 @@ func TestV1ConversionErrorHandling(t *testing.T) { Spec: common.Unstructured{ Object: map[string]interface{}{ "title": "test dashboard", - // Missing required fields that might cause conversion to fail }, }, } @@ -39,15 +37,14 @@ func TestV1ConversionErrorHandling(t *testing.T) { err := Convert_V1beta1_to_V2alpha1(source, target, nil, dsProvider, leProvider) - // Convert_V1beta1_to_V2alpha1 doesn't return error, just sets status - require.NoError(t, err, "Convert_V1beta1_to_V2alpha1 doesn't return error") + // Conversion should succeed + require.NoError(t, err) // Layout should always be set require.NotNil(t, target.Spec.Layout.GridLayoutKind) - // If conversion failed, status should be set - if target.Status.Conversion != nil { - require.True(t, target.Status.Conversion.Failed) - require.NotNil(t, target.Status.Conversion.Error) - } + // Status should be set with success + require.NotNil(t, target.Status.Conversion) + require.False(t, target.Status.Conversion.Failed) + require.Equal(t, dashv1.VERSION, *target.Status.Conversion.StoredVersion) }) t.Run("Convert_V1beta1_to_V2beta1 returns error on first step failure", func(t *testing.T) { @@ -126,3 +123,156 @@ func TestV1ConversionErrorHandling(t *testing.T) { } }) } + +// TestV1ConversionConsistency_ErrorsMustBeReturned ensures v1 conversion functions +// return errors instead of swallowing them. This prevents metrics and logs from being silently dropped. +func TestV1ConversionConsistency_ErrorsMustBeReturned(t *testing.T) { + leProvider := migrationtestutil.NewLibraryElementProvider() + + // Create a valid v1 dashboard - the nil dsProvider will cause conversion to fail + validV1 := &dashv1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "org-1", + Name: "test-dashboard", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 42, + }, + }, + } + + t.Run("Convert_V1beta1_to_V2alpha1 must return error on failure", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + // Pass nil dsProvider to cause conversion to fail + err := Convert_V1beta1_to_V2alpha1(validV1, target, nil, nil, leProvider) + require.Error(t, err, "Convert_V1beta1_to_V2alpha1 must return error, not swallow it") + require.True(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be true") + }) + + t.Run("Convert_V1beta1_to_V2beta1 must return error on failure", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + // Pass nil dsProvider to cause conversion to fail + err := Convert_V1beta1_to_V2beta1(validV1, target, nil, nil, leProvider) + require.Error(t, err, "Convert_V1beta1_to_V2beta1 must return error, not swallow it") + require.True(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be true") + }) +} + +// TestV1ConversionConsistency_SuccessStatusMustBeSet ensures v1 conversion functions +// set Status.Conversion with Failed=false on successful conversion. +func TestV1ConversionConsistency_SuccessStatusMustBeSet(t *testing.T) { + dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) + leProvider := migrationtestutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + // Create a valid v1 dashboard + validV1 := &dashv1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test-dashboard", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 42, + }, + }, + } + + t.Run("Convert_V1beta1_to_V2alpha1 must set success status", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + err := Convert_V1beta1_to_V2alpha1(validV1, target, nil, dsProvider, leProvider) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + require.Equal(t, dashv1.VERSION, *target.Status.Conversion.StoredVersion) + }) + + t.Run("Convert_V1beta1_to_V2beta1 must set success status", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + err := Convert_V1beta1_to_V2beta1(validV1, target, nil, dsProvider, leProvider) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + require.Equal(t, dashv1.VERSION, *target.Status.Conversion.StoredVersion) + }) +} + +// TestV1ConversionConsistency_ObjectMetaMustBeSetOnError ensures v1 conversion functions +// set ObjectMeta, APIVersion, and Kind on the target even when conversion fails. +func TestV1ConversionConsistency_ObjectMetaMustBeSetOnError(t *testing.T) { + leProvider := migrationtestutil.NewLibraryElementProvider() + + validV1 := &dashv1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "org-1", + Name: "test-dashboard", + UID: "test-uid", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 42, + }, + }, + } + + t.Run("Convert_V1beta1_to_V2alpha1 must set ObjectMeta on error", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + // Pass nil dsProvider to cause conversion to fail + err := Convert_V1beta1_to_V2alpha1(validV1, target, nil, nil, leProvider) + require.Error(t, err) + require.Equal(t, validV1.Name, target.Name, "Name must be set on error") + require.Equal(t, validV1.Namespace, target.Namespace, "Namespace must be set on error") + require.Equal(t, dashv2alpha1.APIVERSION, target.APIVersion, "APIVersion must be set on error") + }) + + t.Run("Convert_V1beta1_to_V2beta1 must set ObjectMeta on error", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + // Pass nil dsProvider to cause conversion to fail + err := Convert_V1beta1_to_V2beta1(validV1, target, nil, nil, leProvider) + require.Error(t, err) + require.Equal(t, validV1.Name, target.Name, "Name must be set on error") + require.Equal(t, validV1.Namespace, target.Namespace, "Namespace must be set on error") + require.Equal(t, dashv2beta1.APIVERSION, target.APIVersion, "APIVersion must be set on error") + }) +} + +// TestV1ConversionConsistency_LayoutMustBeSetOnError ensures v2alpha1 and v2beta1 targets +// have a default layout set even when conversion fails to prevent JSON marshaling errors. +func TestV1ConversionConsistency_LayoutMustBeSetOnError(t *testing.T) { + leProvider := migrationtestutil.NewLibraryElementProvider() + + validV1 := &dashv1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "org-1", + Name: "test-dashboard", + }, + Spec: common.Unstructured{ + Object: map[string]interface{}{ + "title": "test dashboard", + "schemaVersion": 42, + }, + }, + } + + t.Run("Convert_V1beta1_to_V2alpha1 must set default layout on error", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + // Pass nil dsProvider to cause conversion to fail + err := Convert_V1beta1_to_V2alpha1(validV1, target, nil, nil, leProvider) + require.Error(t, err) + require.NotNil(t, target.Spec.Layout.GridLayoutKind, "GridLayoutKind must be set on error to prevent JSON marshaling issues") + }) + + t.Run("Convert_V1beta1_to_V2beta1 must set default layout on error", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + // Pass nil dsProvider to cause conversion to fail + err := Convert_V1beta1_to_V2beta1(validV1, target, nil, nil, leProvider) + require.Error(t, err) + require.NotNil(t, target.Spec.Layout.GridLayoutKind, "GridLayoutKind must be set on error to prevent JSON marshaling issues") + }) +} diff --git a/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1.go b/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1.go index 236a4337efb..3eeb61893fa 100644 --- a/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1.go +++ b/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1.go @@ -229,6 +229,46 @@ func getBoolField(m map[string]interface{}, key string, defaultValue bool) bool return defaultValue } +// stripBOM removes Byte Order Mark (BOM) characters from a string. +// BOMs (U+FEFF) can be introduced through copy/paste from certain editors +// and cause CUE validation errors ("illegal byte order mark"). +func stripBOM(s string) string { + return strings.ReplaceAll(s, "\ufeff", "") +} + +// stripBOMFromInterface recursively strips BOM characters from all strings +// in an interface{} value (map, slice, or string). +func stripBOMFromInterface(v interface{}) interface{} { + switch val := v.(type) { + case string: + return stripBOM(val) + case map[string]interface{}: + result := make(map[string]interface{}, len(val)) + for k, v := range val { + result[k] = stripBOMFromInterface(v) + } + return result + case []interface{}: + result := make([]interface{}, len(val)) + for i, item := range val { + result[i] = stripBOMFromInterface(item) + } + return result + default: + return v + } +} + +func getUnionField[T ~string](m map[string]interface{}, key string) *T { + if val, ok := m[key]; ok { + if str, ok := val.(string); ok && str != "" { + result := T(str) + return &result + } + } + return nil +} + // Helper function to create int64 pointer func int64Ptr(i int64) *int64 { return &i @@ -383,7 +423,8 @@ func transformLinks(dashboard map[string]interface{}) []dashv2alpha1.DashboardDa // Optional field - only set if present if url, exists := linkMap["url"]; exists { if urlStr, ok := url.(string); ok { - dashLink.Url = &urlStr + cleanUrl := stripBOM(urlStr) + dashLink.Url = &cleanUrl } } @@ -491,11 +532,9 @@ func convertToRowsLayout(ctx context.Context, panels []interface{}, dsIndexProvi if currentRow != nil { // If currentRow is a hidden-header row (panels before first explicit row), - // set its collapse to match the first explicit row's collapsed value - // This matches frontend behavior: collapse: panel.collapsed + // it should not be collapsed because it will disappear and be visible only in edit mode if currentRow.Spec.HideHeader != nil && *currentRow.Spec.HideHeader { - rowCollapsed := getBoolField(panelMap, "collapsed", false) - currentRow.Spec.Collapse = &rowCollapsed + currentRow.Spec.Collapse = &[]bool{false}[0] } // Flush current row to layout rows = append(rows, *currentRow) @@ -1177,6 +1216,10 @@ func buildQueryVariable(ctx context.Context, varMap map[string]interface{}, comm // If no UID and no type, use default datasourceType = getDefaultDatasourceType(ctx, dsIndexProvider) } + } else if dsStr, ok := datasource.(string); ok && isTemplateVariable(dsStr) { + // Handle datasource variable reference (e.g., "$datasource") + // Only process template variables - other string values are not supported in V2 format + datasourceUID = dsStr } else { datasourceType = getDefaultDatasourceType(ctx, dsIndexProvider) } @@ -1195,6 +1238,7 @@ func buildQueryVariable(ctx context.Context, varMap map[string]interface{}, comm Refresh: transformVariableRefreshToEnum(varMap["refresh"]), Sort: transformVariableSortToEnum(varMap["sort"]), Regex: schemaversion.GetStringValue(varMap, "regex"), + RegexApplyTo: getUnionField[dashv2alpha1.DashboardVariableRegexApplyTo](varMap, "regexApplyTo"), Query: buildDataQueryKindForVariable(varMap["query"], datasourceType), AllowCustomValue: getBoolField(varMap, "allowCustomValue", true), }, @@ -1292,6 +1336,17 @@ func buildCustomVariable(varMap map[string]interface{}, commonProps CommonVariab customVar.Spec.AllValue = &allValue } + if valuesFormat := schemaversion.GetStringValue(varMap, "valuesFormat"); valuesFormat != "" { + switch valuesFormat { + case string(dashv2alpha1.DashboardCustomVariableSpecValuesFormatJson): + format := dashv2alpha1.DashboardCustomVariableSpecValuesFormatJson + customVar.Spec.ValuesFormat = &format + case string(dashv2alpha1.DashboardCustomVariableSpecValuesFormatCsv): + format := dashv2alpha1.DashboardCustomVariableSpecValuesFormatCsv + customVar.Spec.ValuesFormat = &format + } + } + return dashv2alpha1.DashboardVariableKind{ CustomVariableKind: customVar, }, nil @@ -1523,6 +1578,10 @@ func buildAdhocVariable(ctx context.Context, varMap map[string]interface{}, comm // If no UID and no type, use default datasourceType = getDefaultDatasourceType(ctx, dsIndexProvider) } + } else if dsStr, ok := datasource.(string); ok && isTemplateVariable(dsStr) { + // Handle datasource variable reference (e.g., "$datasource") + // Only process template variables - other string values are not supported in V2 format + datasourceUID = dsStr } else { datasourceType = getDefaultDatasourceType(ctx, dsIndexProvider) } @@ -1700,6 +1759,10 @@ func buildGroupByVariable(ctx context.Context, varMap map[string]interface{}, co // Resolve Grafana datasource UID when type is "datasource" and UID is empty datasourceUID = resolveGrafanaDatasourceUID(datasourceType, datasourceUID) + } else if dsStr, ok := datasource.(string); ok && isTemplateVariable(dsStr) { + // Handle datasource variable reference (e.g., "$datasource") + // Only process template variables - other string values are not supported in V2 format + datasourceUID = dsStr } else { datasourceType = getDefaultDatasourceType(ctx, dsIndexProvider) } @@ -1713,7 +1776,9 @@ func buildGroupByVariable(ctx context.Context, varMap map[string]interface{}, co Hide: commonProps.Hide, SkipUrlSync: commonProps.SkipUrlSync, Current: buildVariableCurrent(varMap["current"]), - Multi: getBoolField(varMap, "multi", false), + // We set it to true by default because GroupByVariable + // constructor defaults to multi: true + Multi: getBoolField(varMap, "multi", true), }, } @@ -1994,6 +2059,34 @@ func transformPanelQueries(ctx context.Context, panelMap map[string]interface{}, Uid: &dsUID, } } + } else if dsStr, ok := ds.(string); ok && isTemplateVariable(dsStr) { + // Handle legacy panel datasource as string (template variable reference e.g., "$datasource") + // Only process template variables - other string values are not supported in V2 format + panelDatasource = &dashv2alpha1.DashboardDataSourceRef{ + Uid: &dsStr, + } + } + } + + // Ensure each target has a non-empty refId. We only fill missing refIds; + existingRefIds := make(map[string]bool) + for _, target := range targets { + if targetMap, ok := target.(map[string]interface{}); ok { + if refId := schemaversion.GetStringValue(targetMap, "refId"); refId != "" { + existingRefIds[refId] = true + } + } + } + for _, target := range targets { + targetMap, ok := target.(map[string]interface{}) + if !ok { + continue + } + refId := schemaversion.GetStringValue(targetMap, "refId") + if refId == "" { + refId = nextAvailableRefId(existingRefIds) + targetMap["refId"] = refId + existingRefIds[refId] = true } } @@ -2009,8 +2102,32 @@ func transformPanelQueries(ctx context.Context, panelMap map[string]interface{}, return queries } +// nextAvailableRefId returns the next unused refId using the same sequence as the +// frontend helper (A, B, ..., Z, AA, AB, ...). +func nextAvailableRefId(existing map[string]bool) string { + const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + var refIdFromIndex func(num int) string + refIdFromIndex = func(num int) string { + if num < len(letters) { + return string(letters[num]) + } + return refIdFromIndex(num/len(letters)-1) + string(letters[num%len(letters)]) + } + + for i := 0; ; i++ { + refId := refIdFromIndex(i) + if !existing[refId] { + return refId + } + } +} + func transformSingleQuery(ctx context.Context, targetMap map[string]interface{}, panelDatasource *dashv2alpha1.DashboardDataSourceRef, dsIndexProvider schemaversion.DataSourceIndexProvider) dashv2alpha1.DashboardPanelQueryKind { refId := schemaversion.GetStringValue(targetMap, "refId", "A") + if refId == "" { + refId = "A" + } hidden := getBoolField(targetMap, "hide", false) // Extract datasource from query or use panel datasource @@ -2034,6 +2151,10 @@ func transformSingleQuery(ctx context.Context, targetMap map[string]interface{}, // Resolve Grafana datasource UID when type is "datasource" and UID is empty queryDatasourceUID = resolveGrafanaDatasourceUID(queryDatasourceType, queryDatasourceUID) } + } else if dsStr, ok := targetMap["datasource"].(string); ok && isTemplateVariable(dsStr) { + // Handle legacy target datasource as string (template variable reference e.g., "$datasource") + // Only process template variables - other string values are not supported in V2 format + queryDatasourceUID = dsStr } // Use panel datasource if target datasource is missing or empty @@ -2170,7 +2291,7 @@ func transformDataLinks(panelMap map[string]interface{}) []dashv2alpha1.Dashboar if linkMap, ok := link.(map[string]interface{}); ok { dataLink := dashv2alpha1.DashboardDataLink{ Title: schemaversion.GetStringValue(linkMap, "title"), - Url: schemaversion.GetStringValue(linkMap, "url"), + Url: stripBOM(schemaversion.GetStringValue(linkMap, "url")), } if _, exists := linkMap["targetBlank"]; exists { targetBlank := getBoolField(linkMap, "targetBlank", false) @@ -2184,6 +2305,32 @@ func transformDataLinks(panelMap map[string]interface{}) []dashv2alpha1.Dashboar return result } +// knownPanelProperties lists all properties defined in the Panel schema (dashboard_kind.cue) +// that should NOT be passed to Angular migration handlers. Only "unknown" Angular-specific +// properties should be passed to migration handlers. +var knownPanelProperties = map[string]bool{ + "type": true, "id": true, "pluginVersion": true, "targets": true, + "title": true, "description": true, "transparent": true, "datasource": true, + "gridPos": true, "links": true, "repeat": true, "repeatDirection": true, + "maxPerRow": true, "maxDataPoints": true, "transformations": true, + "interval": true, "timeFrom": true, "timeShift": true, "hideTimeOverride": true, + "timeCompare": true, "libraryPanel": true, "cacheTimeout": true, + "queryCachingTTL": true, "options": true, "fieldConfig": true, "autoMigrateFrom": true, +} + +// extractAngularOptions extracts only the Angular-specific options from a panel map, +// filtering out all known Panel schema properties. This is used to pass just the +// Angular options to migration handlers (e.g., sparkline, valueName, format for singlestat). +func extractAngularOptions(panelMap map[string]interface{}) map[string]interface{} { + result := make(map[string]interface{}) + for key, value := range panelMap { + if !knownPanelProperties[key] { + result[key] = value + } + } + return result +} + func buildVizConfig(panelMap map[string]interface{}) dashv2alpha1.DashboardVizConfigKind { panelType := schemaversion.GetStringValue(panelMap, "type", "timeseries") pluginVersion := schemaversion.GetStringValue(panelMap, "pluginVersion") @@ -2196,7 +2343,10 @@ func buildVizConfig(panelMap map[string]interface{}) dashv2alpha1.DashboardVizCo options := make(map[string]interface{}) if opts, ok := panelMap["options"].(map[string]interface{}); ok { - options = opts + // Deep copy options to avoid modifying the original + for k, v := range opts { + options[k] = v + } } // Add frontend-style default options to match frontend behavior @@ -2207,11 +2357,43 @@ func buildVizConfig(panelMap map[string]interface{}) dashv2alpha1.DashboardVizCo options["legend"] = legend } + // Handle Angular panel migrations + // This replicates the v0→v1 migration logic for panels that weren't migrated yet. + // We check two cases: + // 1. Panel already has autoMigrateFrom set (from v0→v1 migration) - panel type already converted + // 2. Panel type is a known Angular panel - need to convert type AND set autoMigrateFrom + // 3. Panel has original options - need to set autoMigrateFrom and originalOptions + autoMigrateFrom, hasAutoMigrateFrom := panelMap["autoMigrateFrom"].(string) + originalOptions := extractAngularOptions(panelMap) + + if !hasAutoMigrateFrom || autoMigrateFrom == "" { + // Check if panel type is an Angular type that needs migration + if newType := getAngularPanelMigration(panelType, panelMap); newType != "" { + autoMigrateFrom = panelType // Original Angular type + panelType = newType // New modern type + } else if len(originalOptions) > 0 { + autoMigrateFrom = panelType + } + } + + if autoMigrateFrom != "" { + options["__angularMigration"] = map[string]interface{}{ + "autoMigrateFrom": autoMigrateFrom, + "originalOptions": originalOptions, + } + } + + // Strip BOMs from options (may contain dataLinks with URLs that have BOMs) + cleanedOptions := stripBOMFromInterface(options) + if cleanedMap, ok := cleanedOptions.(map[string]interface{}); ok { + options = cleanedMap + } + // Build field config by mapping each field individually fieldConfigSource := extractFieldConfigSource(fieldConfig) return dashv2alpha1.DashboardVizConfigKind{ - Kind: panelType, // Use panelType as Kind (plugin ID) to match schema comment + Kind: panelType, // Use panelType as Kind (plugin ID) - may be converted from Angular type Spec: dashv2alpha1.DashboardVizConfigSpec{ PluginVersion: pluginVersion, FieldConfig: fieldConfigSource, @@ -2350,9 +2532,14 @@ func extractFieldConfigDefaults(defaults map[string]interface{}) dashv2alpha1.Da hasDefaults = true } - // Extract array field + // Extract array field - strip BOMs from link URLs if linksArray, ok := extractArrayField(defaults, "links"); ok { - fieldConfigDefaults.Links = linksArray + cleanedLinks := stripBOMFromInterface(linksArray) + if cleanedArray, ok := cleanedLinks.([]interface{}); ok { + fieldConfigDefaults.Links = cleanedArray + } else { + fieldConfigDefaults.Links = linksArray + } hasDefaults = true } @@ -2507,22 +2694,15 @@ func buildRegexMap(mappingMap map[string]interface{}) *dashv2alpha1.DashboardReg regexMap := &dashv2alpha1.DashboardRegexMap{} regexMap.Type = dashv2alpha1.DashboardMappingTypeRegex - opts, ok := mappingMap["options"].([]interface{}) - if !ok || len(opts) == 0 { - return nil - } - - optMap, ok := opts[0].(map[string]interface{}) + optMap, ok := mappingMap["options"].(map[string]interface{}) if !ok { return nil } r := dashv2alpha1.DashboardV2alpha1RegexMapOptions{} - if pattern, ok := optMap["regex"].(string); ok { + if pattern, ok := optMap["pattern"].(string); ok { r.Pattern = pattern } - - // Result is a DashboardValueMappingResult if resMap, ok := optMap["result"].(map[string]interface{}); ok { r.Result = buildValueMappingResult(resMap) } @@ -2645,9 +2825,11 @@ func extractFieldConfigOverrides(fieldConfig map[string]interface{}) []dashv2alp fieldOverride.Properties = make([]dashv2alpha1.DashboardDynamicConfigValue, 0, len(propertiesArray)) for _, property := range propertiesArray { if propertyMap, ok := property.(map[string]interface{}); ok { + // Strip BOMs from property values (may contain links with URLs) + cleanedValue := stripBOMFromInterface(propertyMap["value"]) fieldOverride.Properties = append(fieldOverride.Properties, dashv2alpha1.DashboardDynamicConfigValue{ Id: schemaversion.GetStringValue(propertyMap, "id"), - Value: propertyMap["value"], + Value: cleanedValue, }) } } @@ -2659,3 +2841,10 @@ func extractFieldConfigOverrides(fieldConfig map[string]interface{}) []dashv2alp return result } + +// getAngularPanelMigration is a convenience wrapper around schemaversion.GetAngularPanelMigration. +// It checks if a panel type is an Angular panel and returns the new type to migrate to. +// Returns the new panel type if migration is needed, empty string otherwise. +func getAngularPanelMigration(panelType string, panelMap map[string]interface{}) string { + return schemaversion.GetAngularPanelMigration(panelType, panelMap) +} diff --git a/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1_test.go b/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1_test.go index 3dad9188fe7..6c0e8f4f919 100644 --- a/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1_test.go +++ b/apps/dashboard/pkg/migration/conversion/v1beta1_to_v2alpha1_test.go @@ -19,7 +19,7 @@ func TestV1beta1ToV2alpha1(t *testing.T) { // Initialize the migrator with test providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() @@ -210,6 +210,48 @@ func TestV1beta1ToV2alpha1(t *testing.T) { assert.Equal(t, "", query.Spec.Query.Kind, "Query kind should be empty when datasource is empty object {}") }, }, + { + name: "missing refIds are assigned while existing refIds are preserved", + createV1beta1: func() *dashv1.Dashboard { + return &dashv1.Dashboard{ + Spec: dashv1.DashboardSpec{ + Object: map[string]interface{}{ + "title": "Test Dashboard", + "panels": []interface{}{ + map[string]interface{}{ + "id": 1, + "type": "bargauge", + "targets": []interface{}{ + map[string]interface{}{ + "refId": "", + "scenarioId": "random_walk", + }, + map[string]interface{}{ + "refId": "A", + "scenarioId": "random_walk", + }, + map[string]interface{}{ + "refId": "", + "scenarioId": "random_walk", + }, + }, + }, + }, + }, + }, + } + }, + validateV2alpha1: func(t *testing.T, v2alpha1 *dashv2alpha1.Dashboard) { + require.NotNil(t, v2alpha1.Spec.Elements["panel-1"]) + panel := v2alpha1.Spec.Elements["panel-1"].PanelKind + require.NotNil(t, panel) + + require.Len(t, panel.Spec.Data.Spec.Queries, 3) + assert.Equal(t, "B", panel.Spec.Data.Spec.Queries[0].Spec.RefId) + assert.Equal(t, "A", panel.Spec.Data.Spec.Queries[1].Spec.RefId) + assert.Equal(t, "C", panel.Spec.Data.Spec.Queries[2].Spec.RefId) + }, + }, } for _, tt := range testCases { diff --git a/apps/dashboard/pkg/migration/conversion/v2.go b/apps/dashboard/pkg/migration/conversion/v2.go index fee798d3ec5..beed5679b85 100644 --- a/apps/dashboard/pkg/migration/conversion/v2.go +++ b/apps/dashboard/pkg/migration/conversion/v2.go @@ -11,10 +11,10 @@ import ( "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion" ) -func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider) error { +func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, scope conversion.Scope) error { // Convert v2alpha1 → v1beta1 first, then v1beta1 → v0 v1beta1 := &dashv1.Dashboard{} - if err := ConvertDashboard_V2alpha1_to_V1beta1(in, v1beta1, scope, dsIndexProvider); err != nil { + if err := ConvertDashboard_V2alpha1_to_V1beta1(in, v1beta1, scope); err != nil { out.ObjectMeta = in.ObjectMeta out.APIVersion = dashv0.APIVERSION out.Kind = in.Kind @@ -26,8 +26,7 @@ func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, s Source: in, }, } - // For errors, set status but don't return error - return nil + return err } // Convert v1beta1 → v0 @@ -43,8 +42,7 @@ func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, s Source: in, }, } - // For errors, set status but don't return error - return nil + return err } // Update the stored version to reflect the original source @@ -53,13 +51,13 @@ func Convert_V2alpha1_to_V0(in *dashv2alpha1.Dashboard, out *dashv0.Dashboard, s return nil } -func Convert_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider) error { +func Convert_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.APIVersion = dashv1.APIVERSION out.Kind = in.Kind // Convert the spec - if err := ConvertDashboard_V2alpha1_to_V1beta1(in, out, scope, dsIndexProvider); err != nil { + if err := ConvertDashboard_V2alpha1_to_V1beta1(in, out, scope); err != nil { out.Status = dashv1.DashboardStatus{ Conversion: &dashv1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv2alpha1.VERSION), @@ -68,9 +66,7 @@ func Convert_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboa Source: in, }, } - - // For errors, set status but don't return error - return nil + return err } // Set successful conversion status @@ -129,8 +125,7 @@ func Convert_V2beta1_to_V0(in *dashv2beta1.Dashboard, out *dashv0.Dashboard, sco Source: in, }, } - // For errors, set status but don't return error - return nil + return err } // Convert v1beta1 → v0 @@ -146,7 +141,7 @@ func Convert_V2beta1_to_V0(in *dashv2beta1.Dashboard, out *dashv0.Dashboard, sco Source: in, }, } - return nil + return err } // Update the stored version to reflect the original source @@ -172,14 +167,13 @@ func Convert_V2beta1_to_V1beta1(in *dashv2beta1.Dashboard, out *dashv1.Dashboard Source: in, }, } - // For errors, set status but don't return error - return nil + return err } // Convert v2alpha1 → v1beta1 // Note: ConvertDashboard_V2alpha1_to_V1beta1 will set out.ObjectMeta from v2alpha1, // but we've already set it from the original input, so it will be preserved - if err := ConvertDashboard_V2alpha1_to_V1beta1(v2alpha1, out, scope, dsIndexProvider); err != nil { + if err := ConvertDashboard_V2alpha1_to_V1beta1(v2alpha1, out, scope); err != nil { out.Status = dashv1.DashboardStatus{ Conversion: &dashv1.DashboardConversionStatus{ StoredVersion: ptr.To(dashv2beta1.VERSION), @@ -188,8 +182,7 @@ func Convert_V2beta1_to_V1beta1(in *dashv2beta1.Dashboard, out *dashv1.Dashboard Source: in, }, } - // For errors, set status but don't return error - return nil + return err } // Set successful conversion status diff --git a/apps/dashboard/pkg/migration/conversion/v2_test.go b/apps/dashboard/pkg/migration/conversion/v2_test.go index 18e0713fa84..3e218da9f81 100644 --- a/apps/dashboard/pkg/migration/conversion/v2_test.go +++ b/apps/dashboard/pkg/migration/conversion/v2_test.go @@ -18,7 +18,7 @@ func TestV2alpha1ConversionErrorHandling(t *testing.T) { // Initialize the migrator with test data source and library element providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) t.Run("Convert_V2alpha1_to_V1beta1 sets status on conversion", func(t *testing.T) { // Create a dashboard for conversion @@ -39,7 +39,7 @@ func TestV2alpha1ConversionErrorHandling(t *testing.T) { } target := &dashv1.Dashboard{} - err := Convert_V2alpha1_to_V1beta1(source, target, nil, dsProvider) + err := Convert_V2alpha1_to_V1beta1(source, target, nil) // Convert_V2alpha1_to_V1beta1 doesn't return error, just sets status require.NoError(t, err, "Convert_V2alpha1_to_V1beta1 doesn't return error") @@ -90,7 +90,7 @@ func TestV2beta1ConversionErrorHandling(t *testing.T) { // Initialize the migrator with test data source and library element providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) t.Run("Convert_V2beta1_to_V1beta1 sets status on first step failure", func(t *testing.T) { // Create a dashboard that might cause conversion to fail on first step (v2beta1 -> v2alpha1) @@ -186,3 +186,141 @@ func TestV2beta1ConversionErrorHandling(t *testing.T) { } }) } + +// TestV2ConversionConsistency_SuccessStatusMustBeSet ensures v2 conversion functions +// set Status.Conversion with Failed=false on successful conversion. +func TestV2ConversionConsistency_SuccessStatusMustBeSet(t *testing.T) { + dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) + leProvider := migrationtestutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + // Create valid v2alpha1 dashboard + validV2alpha1 := &dashv2alpha1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test-dashboard", + }, + Spec: dashv2alpha1.DashboardSpec{ + Title: "test dashboard", + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{}, + }, + }, + }, + } + + // Create valid v2beta1 dashboard + validV2beta1 := &dashv2beta1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test-dashboard", + }, + Spec: dashv2beta1.DashboardSpec{ + Title: "test dashboard", + Layout: dashv2beta1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2beta1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2beta1.DashboardGridLayoutSpec{}, + }, + }, + }, + } + + t.Run("Convert_V2alpha1_to_V1beta1 must set success status", func(t *testing.T) { + target := &dashv1.Dashboard{} + err := Convert_V2alpha1_to_V1beta1(validV2alpha1, target, nil) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + }) + + t.Run("Convert_V2alpha1_to_V2beta1 must set success status", func(t *testing.T) { + target := &dashv2beta1.Dashboard{} + err := Convert_V2alpha1_to_V2beta1(validV2alpha1, target, nil) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + }) + + t.Run("Convert_V2beta1_to_V1beta1 must set success status", func(t *testing.T) { + target := &dashv1.Dashboard{} + err := Convert_V2beta1_to_V1beta1(validV2beta1, target, nil, dsProvider) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + }) + + t.Run("Convert_V2beta1_to_V2alpha1 must set success status", func(t *testing.T) { + target := &dashv2alpha1.Dashboard{} + err := Convert_V2beta1_to_V2alpha1(validV2beta1, target, nil) + require.NoError(t, err) + require.NotNil(t, target.Status.Conversion, "Status.Conversion must be set on success") + require.False(t, target.Status.Conversion.Failed, "Status.Conversion.Failed must be false on success") + require.NotNil(t, target.Status.Conversion.StoredVersion, "StoredVersion must be set") + }) +} + +// TestV2ConversionConsistency_ErrorsMustBeReturned ensures v2 conversion functions +// return errors instead of swallowing them. This prevents metrics and logs from being silently dropped. +func TestV2ConversionConsistency_ErrorsMustBeReturned(t *testing.T) { + dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) + leProvider := migrationtestutil.NewLibraryElementProvider() + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) + + // Note: v2 conversions are harder to make fail since they don't go through schema migration. + // These tests verify that IF an error occurs, it is returned (not swallowed). + // The existing tests already cover this, but we add explicit assertions here. + + t.Run("Convert_V2alpha1_to_V2beta1 returns error on conversion failure", func(t *testing.T) { + // Valid dashboard should succeed + source := &dashv2alpha1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test-dashboard", + }, + Spec: dashv2alpha1.DashboardSpec{ + Title: "test dashboard", + Layout: dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2alpha1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2alpha1.DashboardGridLayoutSpec{}, + }, + }, + }, + } + target := &dashv2beta1.Dashboard{} + err := Convert_V2alpha1_to_V2beta1(source, target, nil) + // This should succeed, verifying the function works + require.NoError(t, err) + require.False(t, target.Status.Conversion.Failed) + }) + + t.Run("Convert_V2beta1_to_V2alpha1 returns error on conversion failure", func(t *testing.T) { + // Valid dashboard should succeed + source := &dashv2beta1.Dashboard{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "default", + Name: "test-dashboard", + }, + Spec: dashv2beta1.DashboardSpec{ + Title: "test dashboard", + Layout: dashv2beta1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashv2beta1.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashv2beta1.DashboardGridLayoutSpec{}, + }, + }, + }, + } + target := &dashv2alpha1.Dashboard{} + err := Convert_V2beta1_to_V2alpha1(source, target, nil) + // This should succeed, verifying the function works + require.NoError(t, err) + require.False(t, target.Status.Conversion.Failed) + }) +} diff --git a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1.go b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1.go index 180a8d603bb..5dc7ecf21fd 100644 --- a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1.go +++ b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1.go @@ -1,14 +1,12 @@ package conversion import ( - "context" "fmt" - "k8s.io/apimachinery/pkg/conversion" - dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1" dashv2alpha1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1" "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion" + "k8s.io/apimachinery/pkg/conversion" ) // ConvertDashboard_V2alpha1_to_V1beta1 converts a v2alpha1 dashboard to v1beta1 format. @@ -16,19 +14,13 @@ import ( // that represents the v1 dashboard JSON format. // The dsIndexProvider is used to resolve default datasources when queries/variables/annotations // don't have explicit datasource references. -func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope, dsIndexProvider schemaversion.DataSourceIndexProvider) error { +func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv1.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta out.APIVersion = dashv1.APIVERSION out.Kind = in.Kind // Preserve the Kind from input (should be "Dashboard") - // Get datasource index for resolving default datasources - var dsIndex *schemaversion.DatasourceIndex - if dsIndexProvider != nil { - dsIndex = dsIndexProvider.Index(context.Background()) - } - // Convert the spec to v1beta1 unstructured format - dashboardJSON, err := convertDashboardSpec_V2alpha1_to_V1beta1(&in.Spec, dsIndex) + dashboardJSON, err := convertDashboardSpec_V2alpha1_to_V1beta1(&in.Spec) if err != nil { return fmt.Errorf("failed to convert dashboard spec: %w", err) } @@ -39,7 +31,7 @@ func ConvertDashboard_V2alpha1_to_V1beta1(in *dashv2alpha1.Dashboard, out *dashv return nil } -func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) { +func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec) (map[string]interface{}, error) { dashboard := make(map[string]interface{}) // Convert basic fields @@ -75,7 +67,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds } // Convert panels from elements and layout - panels, err := convertPanelsFromElementsAndLayout(in.Elements, in.Layout, dsIndex) + panels, err := convertPanelsFromElementsAndLayout(in.Elements, in.Layout) if err != nil { return nil, fmt.Errorf("failed to convert panels: %w", err) } @@ -90,7 +82,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds } // Convert variables - variables := convertVariablesToV1(in.Variables, dsIndex) + variables := convertVariablesToV1(in.Variables) if len(variables) > 0 { dashboard["templating"] = map[string]interface{}{ "list": variables, @@ -98,7 +90,7 @@ func convertDashboardSpec_V2alpha1_to_V1beta1(in *dashv2alpha1.DashboardSpec, ds } // Convert annotations - always include even if empty to prevent DashboardModel from adding built-in - annotations := convertAnnotationsToV1(in.Annotations, dsIndex) + annotations := convertAnnotationsToV1(in.Annotations) dashboard["annotations"] = map[string]interface{}{ "list": annotations, } @@ -236,28 +228,28 @@ func countTotalPanels(panels []interface{}) int { // - RowsLayout: Rows become row panels; nested structures are flattened // - AutoGridLayout: Calculates gridPos based on column count and row height // - TabsLayout: Tabs become expanded row panels; content is flattened -func convertPanelsFromElementsAndLayout(elements map[string]dashv2alpha1.DashboardElement, layout dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) { +func convertPanelsFromElementsAndLayout(elements map[string]dashv2alpha1.DashboardElement, layout dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind) ([]interface{}, error) { if layout.GridLayoutKind != nil { - return convertGridLayoutToPanels(elements, layout.GridLayoutKind, dsIndex) + return convertGridLayoutToPanels(elements, layout.GridLayoutKind) } if layout.RowsLayoutKind != nil { - return convertRowsLayoutToPanels(elements, layout.RowsLayoutKind, dsIndex) + return convertRowsLayoutToPanels(elements, layout.RowsLayoutKind) } if layout.AutoGridLayoutKind != nil { - return convertAutoGridLayoutToPanels(elements, layout.AutoGridLayoutKind, dsIndex) + return convertAutoGridLayoutToPanels(elements, layout.AutoGridLayoutKind) } if layout.TabsLayoutKind != nil { - return convertTabsLayoutToPanels(elements, layout.TabsLayoutKind, dsIndex) + return convertTabsLayoutToPanels(elements, layout.TabsLayoutKind) } // No layout specified, return empty panels return []interface{}{}, nil } -func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, gridLayout *dashv2alpha1.DashboardGridLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) { +func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, gridLayout *dashv2alpha1.DashboardGridLayoutKind) ([]interface{}, error) { panels := make([]interface{}, 0, len(gridLayout.Spec.Items)) for _, item := range gridLayout.Spec.Items { @@ -266,7 +258,7 @@ func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement return nil, fmt.Errorf("panel with uid %s not found in the dashboard elements", item.Spec.Element.Name) } - panel, err := convertPanelFromElement(&element, &item, dsIndex) + panel, err := convertPanelFromElement(&element, &item) if err != nil { return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err) } @@ -279,21 +271,21 @@ func convertGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement // convertRowsLayoutToPanels converts a RowsLayout to V1 panels. // All nested structures (rows within rows, tabs within rows) are flattened to the root level. // Each row becomes a row panel, and nested content is added sequentially after it. -func convertRowsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) { - return convertNestedLayoutToPanels(elements, rowsLayout, nil, dsIndex, 0) +func convertRowsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind) ([]interface{}, error) { + return convertNestedLayoutToPanels(elements, rowsLayout, nil, 0) } // convertNestedLayoutToPanels handles arbitrary nesting of RowsLayout and TabsLayout. // It processes each row/tab in order, tracking Y position to ensure panels don't overlap. // The function recursively flattens nested structures to produce a flat V1 panel array. -func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex, yOffset int64) ([]interface{}, error) { +func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, rowsLayout *dashv2alpha1.DashboardRowsLayoutKind, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, yOffset int64) ([]interface{}, error) { panels := make([]interface{}, 0) currentY := yOffset // Process RowsLayout if rowsLayout != nil { for _, row := range rowsLayout.Spec.Rows { - rowPanels, newY, err := processRowItem(elements, &row, dsIndex, currentY) + rowPanels, newY, err := processRowItem(elements, &row, currentY) if err != nil { return nil, err } @@ -305,7 +297,7 @@ func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardEleme // Process TabsLayout (tabs are converted to rows) if tabsLayout != nil { for _, tab := range tabsLayout.Spec.Tabs { - tabPanels, newY, err := processTabItem(elements, &tab, dsIndex, currentY) + tabPanels, newY, err := processTabItem(elements, &tab, currentY) if err != nil { return nil, err } @@ -324,7 +316,7 @@ func convertNestedLayoutToPanels(elements map[string]dashv2alpha1.DashboardEleme // - Collapsed row: Panels stored inside row.panels with absolute Y positions // - Expanded row: Panels added to top level after the row panel // - Nested layouts: Parent row is preserved; nested content is flattened after it -func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dashv2alpha1.DashboardRowsLayoutRowKind, dsIndex *schemaversion.DatasourceIndex, startY int64) ([]interface{}, int64, error) { +func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dashv2alpha1.DashboardRowsLayoutRowKind, startY int64) ([]interface{}, int64, error) { panels := make([]interface{}, 0) currentY := startY @@ -354,7 +346,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash } // Then process nested rows - nestedPanels, err := convertNestedLayoutToPanels(elements, row.Spec.Layout.RowsLayoutKind, nil, dsIndex, currentY) + nestedPanels, err := convertNestedLayoutToPanels(elements, row.Spec.Layout.RowsLayoutKind, nil, currentY) if err != nil { return nil, 0, err } @@ -387,7 +379,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash } // Then process nested tabs - nestedPanels, err := convertNestedLayoutToPanels(elements, nil, row.Spec.Layout.TabsLayoutKind, dsIndex, currentY) + nestedPanels, err := convertNestedLayoutToPanels(elements, nil, row.Spec.Layout.TabsLayoutKind, currentY) if err != nil { return nil, 0, err } @@ -429,7 +421,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash // Add collapsed panels if row is collapsed (panels use absolute Y positions) if isCollapsed { - collapsedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY+1) + collapsedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY+1) if err != nil { return nil, 0, err } @@ -444,7 +436,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash // Add panels from row layout (only for expanded rows or hidden header rows) if !isCollapsed || isHiddenHeader { - rowPanels, newY, err := extractExpandedPanels(elements, &row.Spec.Layout, dsIndex, currentY, isHiddenHeader, startY) + rowPanels, newY, err := extractExpandedPanels(elements, &row.Spec.Layout, currentY, isHiddenHeader, startY) if err != nil { return nil, 0, err } @@ -459,7 +451,7 @@ func processRowItem(elements map[string]dashv2alpha1.DashboardElement, row *dash // Each tab becomes an expanded row panel (collapsed=false) with an empty panels array. // The tab's content is flattened and added to the top level after the row panel. // Nested layouts within the tab are recursively processed. -func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dashv2alpha1.DashboardTabsLayoutTabKind, dsIndex *schemaversion.DatasourceIndex, startY int64) ([]interface{}, int64, error) { +func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dashv2alpha1.DashboardTabsLayoutTabKind, startY int64) ([]interface{}, int64, error) { panels := make([]interface{}, 0) currentY := startY @@ -487,7 +479,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash // Handle nested layouts inside the tab if tab.Spec.Layout.RowsLayoutKind != nil { // Nested RowsLayout inside tab - nestedPanels, err := convertNestedLayoutToPanels(elements, tab.Spec.Layout.RowsLayoutKind, nil, dsIndex, currentY) + nestedPanels, err := convertNestedLayoutToPanels(elements, tab.Spec.Layout.RowsLayoutKind, nil, currentY) if err != nil { return nil, 0, err } @@ -495,7 +487,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash currentY = getMaxYFromPanels(nestedPanels, currentY) } else if tab.Spec.Layout.TabsLayoutKind != nil { // Nested TabsLayout inside tab - nestedPanels, err := convertNestedLayoutToPanels(elements, nil, tab.Spec.Layout.TabsLayoutKind, dsIndex, currentY) + nestedPanels, err := convertNestedLayoutToPanels(elements, nil, tab.Spec.Layout.TabsLayoutKind, currentY) if err != nil { return nil, 0, err } @@ -503,6 +495,9 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash currentY = getMaxYFromPanels(nestedPanels, currentY) } else if tab.Spec.Layout.GridLayoutKind != nil { // GridLayout inside tab + baseY := currentY + maxY := currentY + for _, item := range tab.Spec.Layout.GridLayoutKind.Spec.Items { element, ok := elements[item.Spec.Element.Name] if !ok { @@ -510,22 +505,24 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash } adjustedItem := item - adjustedItem.Spec.Y = item.Spec.Y + currentY + adjustedItem.Spec.Y = item.Spec.Y + baseY - panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex) + panel, err := convertPanelFromElement(&element, &adjustedItem) if err != nil { return nil, 0, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err) } panels = append(panels, panel) panelEndY := adjustedItem.Spec.Y + item.Spec.Height - if panelEndY > currentY { - currentY = panelEndY + if panelEndY > maxY { + maxY = panelEndY } } + + currentY = maxY } else if tab.Spec.Layout.AutoGridLayoutKind != nil { // AutoGridLayout inside tab - convert with Y offset - autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, tab.Spec.Layout.AutoGridLayoutKind, dsIndex, currentY) + autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, tab.Spec.Layout.AutoGridLayoutKind, currentY) if err != nil { return nil, 0, err } @@ -540,7 +537,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash // Panels are positioned with absolute Y coordinates (baseY + relative Y). // This matches V1 behavior where collapsed row panels store their children // with Y positions as if the row were expanded at that location. -func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex, baseY int64) ([]interface{}, error) { +func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, baseY int64) ([]interface{}, error) { panels := make([]interface{}, 0) if layout.GridLayoutKind != nil { @@ -552,7 +549,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo // Create a copy with adjusted Y position adjustedItem := item adjustedItem.Spec.Y = item.Spec.Y + baseY - panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex) + panel, err := convertPanelFromElement(&element, &adjustedItem) if err != nil { return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err) } @@ -561,7 +558,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo } // Handle AutoGridLayout for collapsed rows with Y offset if layout.AutoGridLayoutKind != nil { - autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, baseY) + autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, baseY) if err != nil { return nil, err } @@ -571,7 +568,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo if layout.RowsLayoutKind != nil { currentY := baseY for _, row := range layout.RowsLayoutKind.Spec.Rows { - nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY) + nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY) if err != nil { return nil, err } @@ -582,7 +579,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo if layout.TabsLayoutKind != nil { currentY := baseY for _, tab := range layout.TabsLayoutKind.Spec.Tabs { - nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, dsIndex, currentY) + nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, currentY) if err != nil { return nil, err } @@ -596,7 +593,7 @@ func extractCollapsedPanelsWithAbsoluteY(elements map[string]dashv2alpha1.Dashbo // extractCollapsedPanelsFromTabLayoutWithAbsoluteY extracts panels from a tab layout with absolute Y. // Similar to extractCollapsedPanelsWithAbsoluteY but handles the tab-specific layout type. -func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex, baseY int64) ([]interface{}, error) { +func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrAutoGridLayoutKindOrTabsLayoutKind, baseY int64) ([]interface{}, error) { panels := make([]interface{}, 0) if layout.GridLayoutKind != nil { @@ -607,7 +604,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2 } adjustedItem := item adjustedItem.Spec.Y = item.Spec.Y + baseY - panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex) + panel, err := convertPanelFromElement(&element, &adjustedItem) if err != nil { return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err) } @@ -615,7 +612,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2 } } if layout.AutoGridLayoutKind != nil { - autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, baseY) + autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, baseY) if err != nil { return nil, err } @@ -624,7 +621,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2 if layout.RowsLayoutKind != nil { currentY := baseY for _, row := range layout.RowsLayoutKind.Spec.Rows { - nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, dsIndex, currentY) + nestedPanels, err := extractCollapsedPanelsWithAbsoluteY(elements, &row.Spec.Layout, currentY) if err != nil { return nil, err } @@ -635,7 +632,7 @@ func extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements map[string]dashv2 if layout.TabsLayoutKind != nil { currentY := baseY for _, tab := range layout.TabsLayoutKind.Spec.Tabs { - nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, dsIndex, currentY) + nestedPanels, err := extractCollapsedPanelsFromTabLayoutWithAbsoluteY(elements, &tab.Spec.Layout, currentY) if err != nil { return nil, err } @@ -679,7 +676,7 @@ func getLayoutHeightFromTab(layout *dashv2alpha1.DashboardGridLayoutKindOrRowsLa // - Explicit row: Add (currentY - 1) to relative Y for absolute positioning // // Returns the panels and the new Y position for the next row. -func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, dsIndex *schemaversion.DatasourceIndex, currentY int64, isHiddenHeader bool, startY int64) ([]interface{}, int64, error) { +func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayoutKindOrTabsLayoutKindOrRowsLayoutKind, currentY int64, isHiddenHeader bool, startY int64) ([]interface{}, int64, error) { panels := make([]interface{}, 0) // For hidden headers, don't track Y changes (matches original behavior) maxY := startY @@ -700,7 +697,7 @@ func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, la } // For hidden headers: don't adjust Y, keep item.Spec.Y as-is - panel, err := convertPanelFromElement(&element, &adjustedItem, dsIndex) + panel, err := convertPanelFromElement(&element, &adjustedItem) if err != nil { return nil, 0, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err) } @@ -725,7 +722,7 @@ func extractExpandedPanels(elements map[string]dashv2alpha1.DashboardElement, la yOffset = currentY - 1 } - autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, dsIndex, yOffset) + autoGridPanels, err := convertAutoGridLayoutToPanelsWithOffset(elements, layout.AutoGridLayoutKind, yOffset) if err != nil { return nil, 0, err } @@ -788,7 +785,7 @@ func getLayoutHeight(layout *dashv2alpha1.DashboardGridLayoutKindOrAutoGridLayou // convertAutoGridLayoutToPanelsWithOffset converts AutoGridLayout with a Y offset. // Same as convertAutoGridLayoutToPanels but starts at yOffset instead of 0. // Used when AutoGridLayout appears inside rows or tabs. -func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, dsIndex *schemaversion.DatasourceIndex, yOffset int64) ([]interface{}, error) { +func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, yOffset int64) ([]interface{}, error) { panels := make([]interface{}, 0, len(autoGridLayout.Spec.Items)) const ( @@ -850,7 +847,7 @@ func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.Da }, } - panel, err := convertPanelFromElement(&element, &gridItem, dsIndex) + panel, err := convertPanelFromElement(&element, &gridItem) if err != nil { return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err) } @@ -876,7 +873,7 @@ func convertAutoGridLayoutToPanelsWithOffset(elements map[string]dashv2alpha1.Da // // Width: 24 / maxColumnCount (default 3 columns = 8 units wide) // Height: Predefined grid units per mode (see pixelsToGridUnits for custom) -func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) { +func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, autoGridLayout *dashv2alpha1.DashboardAutoGridLayoutKind) ([]interface{}, error) { panels := make([]interface{}, 0, len(autoGridLayout.Spec.Items)) const ( @@ -963,7 +960,7 @@ func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardEle } } - panel, err := convertPanelFromElement(&element, &gridItem, dsIndex) + panel, err := convertPanelFromElement(&element, &gridItem) if err != nil { return nil, fmt.Errorf("failed to convert panel %s: %w", item.Spec.Element.Name, err) } @@ -984,11 +981,11 @@ func convertAutoGridLayoutToPanels(elements map[string]dashv2alpha1.DashboardEle // V1 has no native tab concept, so tabs are converted to expanded row panels. // Each tab becomes a row panel (collapsed=false, panels=[]) with its content // flattened to the top level. Tab order is preserved in the output. -func convertTabsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind, dsIndex *schemaversion.DatasourceIndex) ([]interface{}, error) { - return convertNestedLayoutToPanels(elements, nil, tabsLayout, dsIndex, 0) +func convertTabsLayoutToPanels(elements map[string]dashv2alpha1.DashboardElement, tabsLayout *dashv2alpha1.DashboardTabsLayoutKind) ([]interface{}, error) { + return convertNestedLayoutToPanels(elements, nil, tabsLayout, 0) } -func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem *dashv2alpha1.DashboardGridLayoutItemKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) { +func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem *dashv2alpha1.DashboardGridLayoutItemKind) (map[string]interface{}, error) { panel := make(map[string]interface{}) // Set grid position @@ -1017,7 +1014,7 @@ func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem } if element.PanelKind != nil { - return convertPanelKindToV1(element.PanelKind, panel, dsIndex) + return convertPanelKindToV1(element.PanelKind, panel) } if element.LibraryPanelKind != nil { @@ -1027,7 +1024,7 @@ func convertPanelFromElement(element *dashv2alpha1.DashboardElement, layoutItem return nil, fmt.Errorf("element has neither PanelKind nor LibraryPanelKind") } -func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[string]interface{}, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) { +func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[string]interface{}) (map[string]interface{}, error) { spec := panelKind.Spec panel["id"] = int(spec.Id) @@ -1067,17 +1064,22 @@ func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[ } // Convert queries (targets) - targets := make([]map[string]interface{}, 0, len(spec.Data.Spec.Queries)) + // Use []interface{} for consistency with JSON unmarshaling and other code paths + targets := make([]interface{}, 0, len(spec.Data.Spec.Queries)) for _, query := range spec.Data.Spec.Queries { - target := convertPanelQueryToV1(&query, dsIndex) + target := convertPanelQueryToV1(&query) targets = append(targets, target) } panel["targets"] = targets - // Detect mixed datasource - set panel.datasource to "mixed" if queries use different datasources - // This matches the frontend behavior in getPanelDataSource (layoutSerializers/utils.ts) - if mixedDS := detectMixedDatasource(spec.Data.Spec.Queries, dsIndex); mixedDS != nil { - panel["datasource"] = mixedDS + // Set panel-level datasource from queries. + // - If queries use different datasources, set to "mixed" + // - If all queries use the same datasource, set to that datasource + // This is required because the frontend's legacy PanelModel.PanelQueryRunner.run uses panel.datasource + // and some components like CSVExportPage rely on it to resolve the datasource. If undefined, it falls back to the default datasource + // which would overwrite the query's datasource. + if panelDS := getPanelDatasource(spec.Data.Spec.Queries); panelDS != nil { + panel["datasource"] = panelDS } // Convert transformations @@ -1125,7 +1127,7 @@ func convertPanelKindToV1(panelKind *dashv2alpha1.DashboardPanelKind, panel map[ return panel, nil } -func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex *schemaversion.DatasourceIndex) map[string]interface{} { +func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind) map[string]interface{} { target := make(map[string]interface{}) // Copy query spec (excluding refId, hide, datasource which are handled separately) @@ -1150,7 +1152,7 @@ func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex } // Resolve datasource based on V2 input (reuse shared function) - datasource := getDataSourceForQuery(query.Spec.Datasource, query.Spec.Query.Kind, nil) + datasource := getDataSourceForQuery(query.Spec.Datasource, query.Spec.Query.Kind) if datasource != nil { target["datasource"] = datasource } @@ -1164,7 +1166,7 @@ func convertPanelQueryToV1(query *dashv2alpha1.DashboardPanelQueryKind, dsIndex // - Else if queryKind (type) is non-empty → return {type} only // - Else → return nil (no datasource) // Used for variables and annotations. Panel queries use convertPanelQueryToV1Target. -func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, queryKind string, _ *schemaversion.DatasourceIndex) map[string]interface{} { +func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, queryKind string) map[string]interface{} { // Case 1: Explicit datasource with UID provided if explicitDS != nil && explicitDS.Uid != nil && *explicitDS.Uid != "" { datasource := map[string]interface{}{ @@ -1190,16 +1192,39 @@ func getDataSourceForQuery(explicitDS *dashv2alpha1.DashboardDataSourceRef, quer return nil } -// detectMixedDatasource checks if panel queries use different datasources. -// Returns a mixed datasource reference if queries use different datasources, nil otherwise. +// getPanelDatasource determines the panel-level datasource for V1. +// Returns: +// - Mixed datasource reference if queries use different datasources +// - Mixed datasource reference if multiple queries use Dashboard datasource (they fetch from different panels) +// - Dashboard datasource reference if a single query uses Dashboard datasource +// - First query's datasource if all queries use the same datasource +// - nil if no queries exist // Compares based on V2 input without runtime resolution: // - If query has explicit datasource.uid → use that UID and type // - Else → use query.Kind as type (empty UID) -func detectMixedDatasource(queries []dashv2alpha1.DashboardPanelQueryKind, _ *schemaversion.DatasourceIndex) map[string]interface{} { +func getPanelDatasource(queries []dashv2alpha1.DashboardPanelQueryKind) map[string]interface{} { + const sharedDashboardQuery = "-- Dashboard --" + if len(queries) == 0 { return nil } + // Count how many queries use Dashboard datasource + // Multiple dashboard queries need mixed mode because they fetch from different panels + // which may have different underlying datasources + dashboardDsQueryCount := 0 + for _, query := range queries { + if query.Spec.Datasource != nil && query.Spec.Datasource.Uid != nil && *query.Spec.Datasource.Uid == sharedDashboardQuery { + dashboardDsQueryCount++ + } + } + if dashboardDsQueryCount > 1 { + return map[string]interface{}{ + "type": "mixed", + "uid": "-- Mixed --", + } + } + var firstUID, firstType string var hasFirst bool @@ -1234,8 +1259,31 @@ func detectMixedDatasource(queries []dashv2alpha1.DashboardPanelQueryKind, _ *sc } } - // Not mixed - don't set panel-level datasource - return nil + // Handle case when a single query uses Dashboard datasource. + // This is needed for the frontend to properly activate and fetch data from source panels. + // See DashboardDatasourceBehaviour.tsx for more details. + if firstUID == sharedDashboardQuery { + return map[string]interface{}{ + "type": "datasource", + "uid": sharedDashboardQuery, + } + } + + // Not mixed - return the first query's datasource so the panel has a datasource set. + // This is required because the frontend's legacy PanelModel.PanelQueryRunner.run uses panel.datasource + // to resolve the datasource, and if undefined, it falls back to the default datasource + // which then overwrites the query's datasource. + if firstType == "" && firstUID == "" { + return nil + } + result := make(map[string]interface{}) + if firstType != "" { + result["type"] = firstType + } + if firstUID != "" { + result["uid"] = firstUID + } + return result } func convertLibraryPanelKindToV1(libPanelKind *dashv2alpha1.DashboardLibraryPanelKind, panel map[string]interface{}) (map[string]interface{}, error) { @@ -1254,7 +1302,7 @@ func convertLibraryPanelKindToV1(libPanelKind *dashv2alpha1.DashboardLibraryPane return panel, nil } -func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsIndex *schemaversion.DatasourceIndex) []map[string]interface{} { +func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(variables)) for _, variable := range variables { @@ -1262,7 +1310,7 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde var err error if variable.QueryVariableKind != nil { - varMap, err = convertQueryVariableToV1(variable.QueryVariableKind, dsIndex) + varMap, err = convertQueryVariableToV1(variable.QueryVariableKind) } else if variable.DatasourceVariableKind != nil { varMap, err = convertDatasourceVariableToV1(variable.DatasourceVariableKind) } else if variable.CustomVariableKind != nil { @@ -1274,9 +1322,9 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde } else if variable.TextVariableKind != nil { varMap, err = convertTextVariableToV1(variable.TextVariableKind) } else if variable.GroupByVariableKind != nil { - varMap, err = convertGroupByVariableToV1(variable.GroupByVariableKind, dsIndex) + varMap, err = convertGroupByVariableToV1(variable.GroupByVariableKind) } else if variable.AdhocVariableKind != nil { - varMap, err = convertAdhocVariableToV1(variable.AdhocVariableKind, dsIndex) + varMap, err = convertAdhocVariableToV1(variable.AdhocVariableKind) } else if variable.SwitchVariableKind != nil { varMap, err = convertSwitchVariableToV1(variable.SwitchVariableKind) } @@ -1289,7 +1337,7 @@ func convertVariablesToV1(variables []dashv2alpha1.DashboardVariableKind, dsInde return result } -func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) { +func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind) (map[string]interface{}, error) { spec := variable.Spec varMap := map[string]interface{}{ "name": spec.Name, @@ -1320,6 +1368,9 @@ func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind, if spec.Definition != nil { varMap["definition"] = *spec.Definition } + if spec.RegexApplyTo != nil { + varMap["regexApplyTo"] = string(*spec.RegexApplyTo) + } varMap["allowCustomValue"] = spec.AllowCustomValue // Convert query - handle LEGACY_STRING_VALUE_KEY @@ -1336,7 +1387,7 @@ func convertQueryVariableToV1(variable *dashv2alpha1.DashboardQueryVariableKind, } // Resolve datasource - use explicit datasource or resolve from query kind (datasource type)/default - datasource := getDataSourceForQuery(spec.Datasource, spec.Query.Kind, dsIndex) + datasource := getDataSourceForQuery(spec.Datasource, spec.Query.Kind) if datasource != nil { varMap["datasource"] = datasource } @@ -1486,7 +1537,7 @@ func convertTextVariableToV1(variable *dashv2alpha1.DashboardTextVariableKind) ( return varMap, nil } -func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) { +func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableKind) (map[string]interface{}, error) { spec := variable.Spec varMap := map[string]interface{}{ "name": spec.Name, @@ -1509,7 +1560,7 @@ func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableK } // Resolve datasource - GroupBy variables don't have a query kind, so use empty string (will fall back to default) - datasource := getDataSourceForQuery(spec.Datasource, "", dsIndex) + datasource := getDataSourceForQuery(spec.Datasource, "") if datasource != nil { varMap["datasource"] = datasource } @@ -1517,7 +1568,7 @@ func convertGroupByVariableToV1(variable *dashv2alpha1.DashboardGroupByVariableK return varMap, nil } -func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind, dsIndex *schemaversion.DatasourceIndex) (map[string]interface{}, error) { +func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind) (map[string]interface{}, error) { spec := variable.Spec varMap := map[string]interface{}{ "name": spec.Name, @@ -1536,7 +1587,7 @@ func convertAdhocVariableToV1(variable *dashv2alpha1.DashboardAdhocVariableKind, varMap["allowCustomValue"] = spec.AllowCustomValue // Resolve datasource - Adhoc variables don't have a query kind, so use empty string (will fall back to default) - datasource := getDataSourceForQuery(spec.Datasource, "", dsIndex) + datasource := getDataSourceForQuery(spec.Datasource, "") if datasource != nil { varMap["datasource"] = datasource } @@ -1663,7 +1714,7 @@ func convertSwitchVariableToV1(variable *dashv2alpha1.DashboardSwitchVariableKin return varMap, nil } -func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryKind, dsIndex *schemaversion.DatasourceIndex) []map[string]interface{} { +func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryKind) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(annotations)) for _, annotation := range annotations { @@ -1686,7 +1737,7 @@ func convertAnnotationsToV1(annotations []dashv2alpha1.DashboardAnnotationQueryK if annotation.Spec.Query != nil { queryKind = annotation.Spec.Query.Kind } - datasource := getDataSourceForQuery(annotation.Spec.Datasource, queryKind, dsIndex) + datasource := getDataSourceForQuery(annotation.Spec.Datasource, queryKind) if datasource != nil { annotationMap["datasource"] = datasource } @@ -1972,16 +2023,16 @@ func convertFieldConfigOverridesToV1(overrides []dashv2alpha1.DashboardV2alpha1F "options": override.Matcher.Options, } + properties := make([]map[string]interface{}, 0, len(override.Properties)) if len(override.Properties) > 0 { - properties := make([]map[string]interface{}, 0, len(override.Properties)) for _, prop := range override.Properties { properties = append(properties, map[string]interface{}{ "id": prop.Id, "value": prop.Value, }) } - overrideMap["properties"] = properties } + overrideMap["properties"] = properties result = append(result, overrideMap) } @@ -2073,11 +2124,9 @@ func convertRegexMapToV1(regexMap *dashv2alpha1.DashboardRegexMap) map[string]in return nil } - options := []map[string]interface{}{ - { - "pattern": regexMap.Options.Pattern, - "result": convertValueMappingResultToV1(regexMap.Options.Result), - }, + options := map[string]interface{}{ + "pattern": regexMap.Options.Pattern, + "result": convertValueMappingResultToV1(regexMap.Options.Result), } return map[string]interface{}{ diff --git a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1_test.go b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1_test.go index 6ed9804fc68..b3b4fb98395 100644 --- a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1_test.go +++ b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v1beta1_test.go @@ -282,7 +282,7 @@ func TestV2alpha1ToV1beta1LayoutErrors(t *testing.T) { // Initialize the migrator with test data source and library element providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() @@ -498,7 +498,7 @@ func TestV2alpha1ToV1beta1BasicFields(t *testing.T) { // Initialize the migrator with test data source and library element providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() diff --git a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1.go b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1.go index 452f0140047..45803b6d7ec 100644 --- a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1.go +++ b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1.go @@ -685,6 +685,7 @@ func convertVariable_V2alpha1_to_V2beta1(in *dashv2alpha1.DashboardVariableKind, SkipUrlSync: in.CustomVariableKind.Spec.SkipUrlSync, Description: in.CustomVariableKind.Spec.Description, AllowCustomValue: in.CustomVariableKind.Spec.AllowCustomValue, + ValuesFormat: convertCustomValuesFormat_V2alpha1_to_V2beta1(in.CustomVariableKind.Spec.ValuesFormat), }, } } @@ -758,6 +759,23 @@ func convertVariable_V2alpha1_to_V2beta1(in *dashv2alpha1.DashboardVariableKind, return nil } +func convertCustomValuesFormat_V2alpha1_to_V2beta1(in *dashv2alpha1.DashboardCustomVariableSpecValuesFormat) *dashv2beta1.DashboardCustomVariableSpecValuesFormat { + if in == nil { + return nil + } + + switch *in { + case dashv2alpha1.DashboardCustomVariableSpecValuesFormatJson: + v := dashv2beta1.DashboardCustomVariableSpecValuesFormatJson + return &v + case dashv2alpha1.DashboardCustomVariableSpecValuesFormatCsv: + v := dashv2beta1.DashboardCustomVariableSpecValuesFormatCsv + return &v + default: + return nil + } +} + func convertQueryVariableSpec_V2alpha1_to_V2beta1(in *dashv2alpha1.DashboardQueryVariableSpec, out *dashv2beta1.DashboardQueryVariableSpec, scope conversion.Scope) error { out.Name = in.Name out.Current = convertVariableOption_V2alpha1_to_V2beta1(in.Current) @@ -767,6 +785,7 @@ func convertQueryVariableSpec_V2alpha1_to_V2beta1(in *dashv2alpha1.DashboardQuer out.SkipUrlSync = in.SkipUrlSync out.Description = in.Description out.Regex = in.Regex + out.RegexApplyTo = (*dashv2beta1.DashboardVariableRegexApplyTo)(in.RegexApplyTo) out.Sort = dashv2beta1.DashboardVariableSort(in.Sort) out.Definition = in.Definition out.Options = convertVariableOptions_V2alpha1_to_V2beta1(in.Options) diff --git a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1_test.go b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1_test.go index 028197bd655..e92c9215c34 100644 --- a/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1_test.go +++ b/apps/dashboard/pkg/migration/conversion/v2alpha1_to_v2beta1_test.go @@ -18,7 +18,7 @@ func TestV2alpha1ToV2beta1(t *testing.T) { // Initialize the migrator with test providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() diff --git a/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1.go b/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1.go index 95dfcf76c9d..aa7e8e5f36d 100644 --- a/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1.go +++ b/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1.go @@ -806,6 +806,7 @@ func convertQueryVariableSpec_V2beta1_to_V2alpha1(in *dashv2beta1.DashboardQuery out.SkipUrlSync = in.SkipUrlSync out.Description = in.Description out.Regex = in.Regex + out.RegexApplyTo = (*dashv2alpha1.DashboardVariableRegexApplyTo)(in.RegexApplyTo) out.Sort = dashv2alpha1.DashboardVariableSort(in.Sort) out.Definition = in.Definition out.Options = convertVariableOptions_V2beta1_to_V2alpha1(in.Options) diff --git a/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1_test.go b/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1_test.go index 23dcd36ee17..8b84ab40928 100644 --- a/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1_test.go +++ b/apps/dashboard/pkg/migration/conversion/v2beta1_to_v2alpha1_test.go @@ -24,7 +24,7 @@ func TestV2beta1ToV2alpha1RoundTrip(t *testing.T) { // Initialize the migrator with test providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() @@ -107,7 +107,7 @@ func TestV2beta1ToV2alpha1FromOutputFiles(t *testing.T) { // Initialize the migrator with test providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() @@ -193,7 +193,7 @@ func TestV2beta1ToV2alpha1(t *testing.T) { // Initialize the migrator with test providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - migration.Initialize(dsProvider, leProvider) + migration.Initialize(dsProvider, leProvider, migration.DefaultCacheTTL) // Set up conversion scheme scheme := runtime.NewScheme() diff --git a/apps/dashboard/pkg/migration/frontend_defaults.go b/apps/dashboard/pkg/migration/frontend_defaults.go index 1df28c4de27..e8c779406a6 100644 --- a/apps/dashboard/pkg/migration/frontend_defaults.go +++ b/apps/dashboard/pkg/migration/frontend_defaults.go @@ -940,31 +940,12 @@ func applyPanelAutoMigration(panel map[string]interface{}) { return } - var newType string - // Graph needs special logic as it can be migrated to multiple panels // Including graphite which was previously migrated to graph in the schema version 2 migration in DashboardMigrator.ts // but this was a bug because in there graphite was set to graph, but since those migrations run // after PanelModel.restoreModel where autoMigrateFrom is set, this caused the graph migration to be skipped. // And this resulted in a dashboard with invalid panels. - if panelType == "graph" || panelType == "graphite" { - // Check xaxis mode for special cases - newType = getGraphAutoMigration(panel) - } else { - // Check autoMigrateAngular mapping - autoMigrateAngular := map[string]string{ - "table-old": "table", - "singlestat": "stat", - "grafana-singlestat-panel": "stat", - "grafana-piechart-panel": "piechart", - "grafana-worldmap-panel": "geomap", - "natel-discrete-panel": "state-timeline", - } - - if mappedType, exists := autoMigrateAngular[panelType]; exists { - newType = mappedType - } - } + newType := schemaversion.GetAngularPanelMigration(panelType, panel) // Apply auto-migration if a new type was determined if newType != "" { @@ -973,36 +954,6 @@ func applyPanelAutoMigration(panel map[string]interface{}) { } } -func getGraphAutoMigration(panel map[string]interface{}) string { - newType := "" - if xaxis, ok := panel["xaxis"].(map[string]interface{}); ok { - if mode, ok := xaxis["mode"].(string); ok { - switch mode { - case "series": - // Check legend values for bargauge - if legend, ok := panel["legend"].(map[string]interface{}); ok { - if values, ok := legend["values"].(bool); ok && values { - newType = "bargauge" - } else { - newType = "barchart" - } - } else { - newType = "barchart" - } - case "histogram": - newType = "histogram" - } - } - } - - // Default graph migration to timeseries - if newType == "" { - newType = "timeseries" - } - - return newType -} - // removeNullValuesRecursively removes null values from nested objects and arrays // This matches the frontend's JSON.stringify/parse behavior func removeNullValuesRecursively(data interface{}) { diff --git a/apps/dashboard/pkg/migration/migrate.go b/apps/dashboard/pkg/migration/migrate.go index 9c87a45b2db..d1b0fcbb7af 100644 --- a/apps/dashboard/pkg/migration/migrate.go +++ b/apps/dashboard/pkg/migration/migrate.go @@ -4,13 +4,19 @@ import ( "context" "fmt" "sync" + "time" + "github.com/grafana/authlib/types" + "github.com/grafana/grafana-app-sdk/logging" "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion" ) +// DefaultCacheTTL is the default TTL for the datasource and library element caches. +const DefaultCacheTTL = time.Minute + // Initialize provides the migrator singleton with required dependencies and builds the map of migrations. -func Initialize(dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) { - migratorInstance.init(dsIndexProvider, leIndexProvider) +func Initialize(dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider, cacheTTL time.Duration) { + migratorInstance.init(dsIndexProvider, leIndexProvider, cacheTTL) } // GetDataSourceIndexProvider returns the datasource index provider instance that was initialized. @@ -38,6 +44,34 @@ func ResetForTesting() { initOnce = sync.Once{} } +// PreloadCache preloads the datasource and library element caches for the given namespaces. +func PreloadCache(ctx context.Context, nsInfos []types.NamespaceInfo) { + // Wait for initialization to complete + <-migratorInstance.ready + + // Try to preload datasource cache + if preloadable, ok := migratorInstance.dsIndexProvider.(schemaversion.PreloadableCache); ok { + preloadable.Preload(ctx, nsInfos) + } + + // Try to preload library element cache + if preloadable, ok := migratorInstance.leIndexProvider.(schemaversion.PreloadableCache); ok { + preloadable.Preload(ctx, nsInfos) + } +} + +// PreloadCacheInBackground starts a goroutine that preloads the caches for the given namespaces. +func PreloadCacheInBackground(nsInfos []types.NamespaceInfo) { + go func() { + defer func() { + if r := recover(); r != nil { + logging.DefaultLogger.Error("panic during cache preloading", "error", r) + } + }() + PreloadCache(context.Background(), nsInfos) + }() +} + // Migrate migrates the given dashboard to the target version. // This will block until the migrator is initialized. func Migrate(ctx context.Context, dash map[string]interface{}, targetVersion int) error { @@ -59,11 +93,15 @@ type migrator struct { leIndexProvider schemaversion.LibraryElementIndexProvider } -func (m *migrator) init(dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider) { +func (m *migrator) init(dsIndexProvider schemaversion.DataSourceIndexProvider, leIndexProvider schemaversion.LibraryElementIndexProvider, cacheTTL time.Duration) { initOnce.Do(func() { - m.dsIndexProvider = dsIndexProvider - m.leIndexProvider = leIndexProvider - m.migrations = schemaversion.GetMigrations(dsIndexProvider, leIndexProvider) + // Wrap the provider with org-aware TTL caching for all conversions. + // This prevents repeated DB queries across multiple conversion calls while allowing + // the cache to refresh periodically, making it suitable for long-lived singleton usage. + m.dsIndexProvider = schemaversion.WrapIndexProviderWithCache(dsIndexProvider, cacheTTL) + // Wrap library element provider with caching as well + m.leIndexProvider = schemaversion.WrapLibraryElementProviderWithCache(leIndexProvider, cacheTTL) + m.migrations = schemaversion.GetMigrations(m.dsIndexProvider, m.leIndexProvider) close(m.ready) }) } diff --git a/apps/dashboard/pkg/migration/migrate_test.go b/apps/dashboard/pkg/migration/migrate_test.go index 8bb150f91ca..4fe4ea90a60 100644 --- a/apps/dashboard/pkg/migration/migrate_test.go +++ b/apps/dashboard/pkg/migration/migrate_test.go @@ -10,10 +10,13 @@ import ( "path/filepath" "strconv" "strings" + "sync/atomic" "testing" "github.com/prometheus/client_golang/prometheus" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "k8s.io/apiserver/pkg/endpoints/request" "github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion" migrationtestutil "github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil" @@ -31,7 +34,7 @@ func TestMigrate(t *testing.T) { ResetForTesting() dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - Initialize(dsProvider, leProvider) + Initialize(dsProvider, leProvider, DefaultCacheTTL) t.Run("minimum version check", func(t *testing.T) { err := Migrate(context.Background(), map[string]interface{}{ @@ -49,7 +52,7 @@ func TestMigrateSingleVersion(t *testing.T) { // Use the same datasource provider as the frontend test to ensure consistency dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - Initialize(dsProvider, leProvider) + Initialize(dsProvider, leProvider, DefaultCacheTTL) runSingleVersionMigrationTests(t, SINGLE_VERSION_OUTPUT_DIR) } @@ -218,7 +221,7 @@ func TestSchemaMigrationMetrics(t *testing.T) { // Initialize migration with test providers dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - Initialize(dsProvider, leProvider) + Initialize(dsProvider, leProvider, DefaultCacheTTL) // Create a test registry for metrics registry := prometheus.NewRegistry() @@ -304,7 +307,7 @@ func TestSchemaMigrationMetrics(t *testing.T) { func TestSchemaMigrationLogging(t *testing.T) { dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.StandardTestConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - Initialize(dsProvider, leProvider) + Initialize(dsProvider, leProvider, DefaultCacheTTL) tests := []struct { name string @@ -423,7 +426,7 @@ func TestMigrateDevDashboards(t *testing.T) { ResetForTesting() dsProvider := migrationtestutil.NewDataSourceProvider(migrationtestutil.DevDashboardConfig) leProvider := migrationtestutil.NewLibraryElementProvider() - Initialize(dsProvider, leProvider) + Initialize(dsProvider, leProvider, DefaultCacheTTL) runDevDashboardMigrationTests(t, schemaversion.LATEST_VERSION, DEV_DASHBOARDS_OUTPUT_DIR) } @@ -449,3 +452,232 @@ func runDevDashboardMigrationTests(t *testing.T, targetVersion int, outputDir st }) } } + +func TestMigrateWithCache(t *testing.T) { + // Reset the migration singleton before each test + ResetForTesting() + datasources := []schemaversion.DataSourceInfo{ + {UID: "ds-uid-1", Type: "prometheus", Name: "Prometheus", Default: true, APIVersion: "v1"}, + {UID: "ds-uid-2", Type: "loki", Name: "Loki", Default: false, APIVersion: "v1"}, + {UID: "ds-uid-3", Type: "prometheus", Name: "Prometheus 2", Default: false, APIVersion: "v1"}, + } + + // Create a dashboard at schema version 32 for V33 and V36 migration with datasource references + dashboard1 := map[string]interface{}{ + "schemaVersion": 32, + "title": "Test Dashboard 1", + "panels": []interface{}{ + map[string]interface{}{ + "id": 1, + "type": "timeseries", + // String datasource that V33 will migrate to object reference + "datasource": "Prometheus", + "targets": []interface{}{ + map[string]interface{}{ + "refId": "A", + "datasource": "Loki", + }, + }, + }, + }, + } + + // Create a dashboard at schema version 35 for testing V36 migration with datasource references in annotations + dashboard2 := map[string]interface{}{ + "schemaVersion": 35, + "title": "Test Dashboard 2", + "annotations": map[string]interface{}{ + "list": []interface{}{ + map[string]interface{}{ + "name": "Test Annotation", + "datasource": "Prometheus 2", // String reference that V36 should convert + "enable": true, + }, + }, + }, + } + + t.Run("with datasources", func(t *testing.T) { + ResetForTesting() + dsProvider := newCountingProvider(datasources) + leProvider := newCountingLibraryProvider(nil) + // Initialize the migration system with our counting providers + Initialize(dsProvider, leProvider, DefaultCacheTTL) + // Verify initial call count is zero + assert.Equal(t, dsProvider.GetCallCount(), int64(0)) + // Create a context with namespace (required for caching) + ctx := request.WithNamespace(context.Background(), "default") + + // First migration - should invoke the provider once to build the cache + dash1 := deepCopyDashboard(dashboard1) + err := Migrate(ctx, dash1, schemaversion.LATEST_VERSION) + require.NoError(t, err) + assert.Equal(t, int64(1), dsProvider.GetCallCount()) + + // Verify datasource conversion from string to object reference + panels := dash1["panels"].([]interface{}) + panel := panels[0].(map[string]interface{}) + panelDS, ok := panel["datasource"].(map[string]interface{}) + require.True(t, ok, "panel datasource should be converted to object") + assert.Equal(t, "ds-uid-1", panelDS["uid"]) + assert.Equal(t, "prometheus", panelDS["type"]) + + // Verify target datasource conversion + targets := panel["targets"].([]interface{}) + target := targets[0].(map[string]interface{}) + targetDS, ok := target["datasource"].(map[string]interface{}) + require.True(t, ok, "target datasource should be converted to object") + assert.Equal(t, "ds-uid-2", targetDS["uid"]) + assert.Equal(t, "loki", targetDS["type"]) + + // Migration with V35 dashboard - should use the cached index from first migration + dash2 := deepCopyDashboard(dashboard2) + err = Migrate(ctx, dash2, schemaversion.LATEST_VERSION) + require.NoError(t, err, "second migration should succeed") + assert.Equal(t, int64(1), dsProvider.GetCallCount()) + + // Verify the annotation datasource was converted to object reference + annotations := dash2["annotations"].(map[string]interface{}) + list := annotations["list"].([]interface{}) + var testAnnotation map[string]interface{} + for _, a := range list { + ann := a.(map[string]interface{}) + if ann["name"] == "Test Annotation" { + testAnnotation = ann + break + } + } + require.NotNil(t, testAnnotation, "Test Annotation should exist") + annotationDS, ok := testAnnotation["datasource"].(map[string]interface{}) + require.True(t, ok, "annotation datasource should be converted to object") + assert.Equal(t, "ds-uid-3", annotationDS["uid"]) + assert.Equal(t, "prometheus", annotationDS["type"]) + }) + + // tests that cache isolates data per namespace + t.Run("with multiple orgs", func(t *testing.T) { + // Reset the migration singleton + ResetForTesting() + dsProvider := newCountingProvider(datasources) + leProvider := newCountingLibraryProvider(nil) + Initialize(dsProvider, leProvider, DefaultCacheTTL) + // Create contexts for different orgs with proper namespace format (org-ID) + ctx1 := request.WithNamespace(context.Background(), "default") // org 1 + ctx2 := request.WithNamespace(context.Background(), "stacks-2") // stack 2 + + // Migrate for org 1 + err := Migrate(ctx1, deepCopyDashboard(dashboard1), schemaversion.LATEST_VERSION) + require.NoError(t, err) + callsAfterOrg1 := dsProvider.GetCallCount() + + // Migrate for org 2 - should build separate cache + err = Migrate(ctx2, deepCopyDashboard(dashboard2), schemaversion.LATEST_VERSION) + require.NoError(t, err) + callsAfterOrg2 := dsProvider.GetCallCount() + + assert.Greater(t, callsAfterOrg2, callsAfterOrg1, + "org 2 migration should have called provider (separate cache)") + + // Migrate again for org 1 - should use cache + err = Migrate(ctx1, deepCopyDashboard(dashboard1), schemaversion.LATEST_VERSION) + require.NoError(t, err) + callsAfterOrg1Again := dsProvider.GetCallCount() + assert.Equal(t, callsAfterOrg2, callsAfterOrg1Again, + "second org 1 migration should use cache") + + // Migrate again for org 2 - should use cache + err = Migrate(ctx2, deepCopyDashboard(dashboard1), schemaversion.LATEST_VERSION) + require.NoError(t, err) + callsAfterOrg2Again := dsProvider.GetCallCount() + assert.Equal(t, callsAfterOrg2, callsAfterOrg2Again, + "second org 2 migration should use cache") + }) +} + +// countingProvider wraps a datasource provider and counts calls to Index() +type countingProvider struct { + datasources []schemaversion.DataSourceInfo + callCount atomic.Int64 +} + +func newCountingProvider(datasources []schemaversion.DataSourceInfo) *countingProvider { + return &countingProvider{ + datasources: datasources, + } +} + +func (p *countingProvider) Index(_ context.Context) *schemaversion.DatasourceIndex { + p.callCount.Add(1) + return schemaversion.NewDatasourceIndex(p.datasources) +} + +func (p *countingProvider) GetCallCount() int64 { + return p.callCount.Load() +} + +// countingLibraryProvider wraps a library element provider and counts calls +type countingLibraryProvider struct { + elements []schemaversion.LibraryElementInfo + callCount atomic.Int64 +} + +func newCountingLibraryProvider(elements []schemaversion.LibraryElementInfo) *countingLibraryProvider { + return &countingLibraryProvider{ + elements: elements, + } +} + +func (p *countingLibraryProvider) GetLibraryElementInfo(_ context.Context) []schemaversion.LibraryElementInfo { + p.callCount.Add(1) + return p.elements +} + +func (p *countingLibraryProvider) GetCallCount() int64 { + return p.callCount.Load() +} + +// deepCopyDashboard creates a deep copy of a dashboard map +func deepCopyDashboard(dash map[string]interface{}) map[string]interface{} { + cpy := make(map[string]interface{}) + for k, v := range dash { + switch val := v.(type) { + case []interface{}: + cpy[k] = deepCopySlice(val) + case map[string]interface{}: + cpy[k] = deepCopyMapForCache(val) + default: + cpy[k] = v + } + } + return cpy +} + +func deepCopySlice(s []interface{}) []interface{} { + cpy := make([]interface{}, len(s)) + for i, v := range s { + switch val := v.(type) { + case []interface{}: + cpy[i] = deepCopySlice(val) + case map[string]interface{}: + cpy[i] = deepCopyMapForCache(val) + default: + cpy[i] = v + } + } + return cpy +} + +func deepCopyMapForCache(m map[string]interface{}) map[string]interface{} { + cpy := make(map[string]interface{}) + for k, v := range m { + switch val := v.(type) { + case []interface{}: + cpy[k] = deepCopySlice(val) + case map[string]interface{}: + cpy[k] = deepCopyMapForCache(val) + default: + cpy[k] = v + } + } + return cpy +} diff --git a/apps/dashboard/pkg/migration/schemaversion/cache.go b/apps/dashboard/pkg/migration/schemaversion/cache.go new file mode 100644 index 00000000000..2548c2cc5ba --- /dev/null +++ b/apps/dashboard/pkg/migration/schemaversion/cache.go @@ -0,0 +1,100 @@ +package schemaversion + +import ( + "context" + "sync" + "time" + + "github.com/hashicorp/golang-lru/v2/expirable" + "k8s.io/apiserver/pkg/endpoints/request" + + "github.com/grafana/authlib/types" + "github.com/grafana/grafana-app-sdk/logging" +) + +const defaultCacheSize = 1000 + +// CacheProvider is a generic cache interface for schema version providers. +type CacheProvider[T any] interface { + // Get returns the cached value if it's still valid, otherwise calls fetch and caches the result. + Get(ctx context.Context) T +} + +// PreloadableCache is an interface for providers that support preloading the cache. +type PreloadableCache interface { + // Preload loads data into the cache for the given namespaces. + Preload(ctx context.Context, nsInfos []types.NamespaceInfo) +} + +// cachedProvider is a thread-safe TTL cache that wraps any fetch function. +type cachedProvider[T any] struct { + fetch func(context.Context) T + cache *expirable.LRU[string, T] // LRU cache: namespace to cache entry + inFlight sync.Map // map[string]*sync.Mutex - per-namespace fetch locks +} + +// newCachedProvider creates a new cachedProvider. +// The fetch function should be able to handle context with different namespaces. +// A non-positive size turns LRU mechanism off (cache of unlimited size). +// A non-positive cacheTTL disables TTL expiration. +func newCachedProvider[T any](fetch func(context.Context) T, size int, cacheTTL time.Duration) *cachedProvider[T] { + cacheProvider := &cachedProvider[T]{ + fetch: fetch, + } + cacheProvider.cache = expirable.NewLRU(size, func(key string, value T) { + cacheProvider.inFlight.Delete(key) + }, cacheTTL) + return cacheProvider +} + +// Get returns the cached value if it's still valid, otherwise calls fetch and caches the result. +func (p *cachedProvider[T]) Get(ctx context.Context) T { + // Get namespace info from ctx + namespace, ok := request.NamespaceFrom(ctx) + if !ok { + // No namespace, fall back to direct fetch call without caching + logging.FromContext(ctx).Warn("Unable to get namespace info from context, skipping cache") + return p.fetch(ctx) + } + + // Fast path: check if cache is still valid + if entry, ok := p.cache.Get(namespace); ok { + return entry + } + + // Get or create a per-namespace lock for this fetch operation + // This ensures only one fetch happens per namespace at a time + lockInterface, _ := p.inFlight.LoadOrStore(namespace, &sync.Mutex{}) + nsMutex := lockInterface.(*sync.Mutex) + + // Lock this specific namespace - other namespaces can still proceed + nsMutex.Lock() + defer nsMutex.Unlock() + + // Double-check: another goroutine might have already fetched while we waited + if entry, ok := p.cache.Get(namespace); ok { + return entry + } + + // Fetch outside the main lock - only this namespace is blocked + logging.FromContext(ctx).Debug("cache miss or expired, fetching new value", "namespace", namespace) + value := p.fetch(ctx) + + // Update the cache for this namespace + p.cache.Add(namespace, value) + + return value +} + +// Preload loads data into the cache for the given namespaces. +func (p *cachedProvider[T]) Preload(ctx context.Context, nsInfos []types.NamespaceInfo) { + // Build the cache using a context with the namespace + logging.FromContext(ctx).Info("preloading cache", "nsInfos", len(nsInfos)) + startedAt := time.Now() + defer func() { + logging.FromContext(ctx).Info("finished preloading cache", "nsInfos", len(nsInfos), "elapsed", time.Since(startedAt)) + }() + for _, nsInfo := range nsInfos { + p.cache.Add(nsInfo.Value, p.fetch(request.WithNamespace(ctx, nsInfo.Value))) + } +} diff --git a/apps/dashboard/pkg/migration/schemaversion/cache_test.go b/apps/dashboard/pkg/migration/schemaversion/cache_test.go new file mode 100644 index 00000000000..081455143e4 --- /dev/null +++ b/apps/dashboard/pkg/migration/schemaversion/cache_test.go @@ -0,0 +1,478 @@ +package schemaversion + +import ( + "context" + "fmt" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "k8s.io/apiserver/pkg/endpoints/request" + + authlib "github.com/grafana/authlib/types" +) + +// testProvider tracks how many times get() is called +type testProvider struct { + testData any + callCount atomic.Int64 +} + +func newTestProvider(testData any) *testProvider { + return &testProvider{ + testData: testData, + } +} + +func (p *testProvider) get(_ context.Context) any { + p.callCount.Add(1) + return p.testData +} + +func (p *testProvider) getCallCount() int64 { + return p.callCount.Load() +} + +func TestCachedProvider_CacheHit(t *testing.T) { + datasources := []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + {UID: "ds2", Type: "loki", Name: "Loki"}, + } + + underlying := newTestProvider(datasources) + // Test newCachedProvider directly instead of the wrapper + cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute) + + // Use "default" namespace (org 1) - this is the standard Grafana namespace format + ctx := request.WithNamespace(context.Background(), "default") + + // First call should hit the underlying provider + idx1 := cached.Get(ctx) + require.NotNil(t, idx1) + assert.Equal(t, int64(1), underlying.getCallCount(), "first call should invoke underlying provider") + + // Second call should use cache + idx2 := cached.Get(ctx) + require.NotNil(t, idx2) + assert.Equal(t, int64(1), underlying.getCallCount(), "second call should use cache, not invoke underlying provider") + + // Both should return the same data + assert.Equal(t, idx1, idx2) +} + +func TestCachedProvider_NamespaceIsolation(t *testing.T) { + datasources := []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + + underlying := newTestProvider(datasources) + cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute) + + // Use "default" (org 1) and "org-2" (org 2) - standard Grafana namespace formats + ctx1 := request.WithNamespace(context.Background(), "default") + ctx2 := request.WithNamespace(context.Background(), "org-2") + + // First call for org 1 + idx1 := cached.Get(ctx1) + require.NotNil(t, idx1) + assert.Equal(t, int64(1), underlying.getCallCount(), "first org-1 call should invoke underlying provider") + + // Call for org 2 should also invoke underlying provider (different namespace) + idx2 := cached.Get(ctx2) + require.NotNil(t, idx2) + assert.Equal(t, int64(2), underlying.getCallCount(), "org-2 call should invoke underlying provider (separate cache)") + + // Second call for org 1 should use cache + idx3 := cached.Get(ctx1) + require.NotNil(t, idx3) + assert.Equal(t, int64(2), underlying.getCallCount(), "second org-1 call should use cache") + + // Second call for org 2 should use cache + idx4 := cached.Get(ctx2) + require.NotNil(t, idx4) + assert.Equal(t, int64(2), underlying.getCallCount(), "second org-2 call should use cache") +} + +func TestCachedProvider_NoNamespaceFallback(t *testing.T) { + datasources := []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + + underlying := newTestProvider(datasources) + cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute) + + // Context without namespace - should fall back to direct provider call + ctx := context.Background() + + idx1 := cached.Get(ctx) + require.NotNil(t, idx1) + assert.Equal(t, int64(1), underlying.getCallCount()) + + // Second call without namespace should also invoke underlying (no caching for unknown namespace) + idx2 := cached.Get(ctx) + require.NotNil(t, idx2) + assert.Equal(t, int64(2), underlying.getCallCount(), "without namespace, each call should invoke underlying provider") +} + +func TestCachedProvider_ConcurrentAccess(t *testing.T) { + datasources := []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + + underlying := newTestProvider(datasources) + cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute) + + // Use "default" namespace (org 1) + ctx := request.WithNamespace(context.Background(), "default") + + var wg sync.WaitGroup + numGoroutines := 100 + + // Launch many goroutines that all try to access the cache simultaneously + for i := 0; i < numGoroutines; i++ { + wg.Add(1) + go func() { + defer wg.Done() + idx := cached.Get(ctx) + require.NotNil(t, idx) + }() + } + + wg.Wait() + + // Due to double-check locking, only 1 goroutine should have actually built the cache + // In practice, there might be a few more due to timing, but it should be much less than numGoroutines + callCount := underlying.getCallCount() + assert.LessOrEqual(t, callCount, int64(5), "with proper locking, very few goroutines should invoke underlying provider; got %d", callCount) +} + +func TestCachedProvider_ConcurrentNamespaces(t *testing.T) { + datasources := []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + + underlying := newTestProvider(datasources) + cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute) + + var wg sync.WaitGroup + numOrgs := 10 + callsPerOrg := 20 + + // Launch goroutines for multiple namespaces + // Use valid namespace formats: "default" for org 1, "org-N" for N > 1 + namespaces := make([]string, numOrgs) + namespaces[0] = "default" + for i := 1; i < numOrgs; i++ { + namespaces[i] = fmt.Sprintf("org-%d", i+1) + } + + for _, ns := range namespaces { + ctx := request.WithNamespace(context.Background(), ns) + for i := 0; i < callsPerOrg; i++ { + wg.Add(1) + go func(ctx context.Context) { + defer wg.Done() + idx := cached.Get(ctx) + require.NotNil(t, idx) + }(ctx) + } + } + + wg.Wait() + + // Each org should have at most a few calls (ideally 1, but timing can cause a few more) + callCount := underlying.getCallCount() + // With 10 orgs, we expect around 10 calls (one per org) + assert.LessOrEqual(t, callCount, int64(numOrgs), "expected roughly one call per org, got %d calls for %d orgs", callCount, numOrgs) +} + +// Test that cache returns correct data for each namespace +func TestCachedProvider_CorrectDataPerNamespace(t *testing.T) { + // Provider that returns different data based on namespace + underlying := &namespaceAwareProvider{ + datasourcesByNamespace: map[string][]DataSourceInfo{ + "default": {{UID: "org1-ds", Type: "prometheus", Name: "Org1 DS", Default: true}}, + "org-2": {{UID: "org2-ds", Type: "loki", Name: "Org2 DS", Default: true}}, + }, + } + cached := newCachedProvider(underlying.Index, defaultCacheSize, time.Minute) + + // Use valid namespace formats + ctx1 := request.WithNamespace(context.Background(), "default") + ctx2 := request.WithNamespace(context.Background(), "org-2") + + idx1 := cached.Get(ctx1) + idx2 := cached.Get(ctx2) + + assert.Equal(t, "org1-ds", idx1.GetDefault().UID, "org 1 should get org-1 datasources") + assert.Equal(t, "org2-ds", idx2.GetDefault().UID, "org 2 should get org-2 datasources") + + // Subsequent calls should still return correct data + idx1Again := cached.Get(ctx1) + idx2Again := cached.Get(ctx2) + + assert.Equal(t, "org1-ds", idx1Again.GetDefault().UID, "org 1 should still get org-1 datasources from cache") + assert.Equal(t, "org2-ds", idx2Again.GetDefault().UID, "org 2 should still get org-2 datasources from cache") +} + +// TestCachedProvider_PreloadMultipleNamespaces verifies preloading multiple namespaces +func TestCachedProvider_PreloadMultipleNamespaces(t *testing.T) { + // Provider that returns different data based on namespace + underlying := &namespaceAwareProvider{ + datasourcesByNamespace: map[string][]DataSourceInfo{ + "default": {{UID: "org1-ds", Type: "prometheus", Name: "Org1 DS", Default: true}}, + "org-2": {{UID: "org2-ds", Type: "loki", Name: "Org2 DS", Default: true}}, + "org-3": {{UID: "org3-ds", Type: "tempo", Name: "Org3 DS", Default: true}}, + }, + } + cached := newCachedProvider(underlying.Index, defaultCacheSize, time.Minute) + + // Preload multiple namespaces + nsInfos := []authlib.NamespaceInfo{ + createNamespaceInfo(1, 0, "default"), + createNamespaceInfo(2, 0, "org-2"), + createNamespaceInfo(3, 0, "org-3"), + } + cached.Preload(context.Background(), nsInfos) + + // After preload, the underlying provider should have been called once per namespace + assert.Equal(t, 3, underlying.callCount, "preload should call underlying provider once per namespace") + + // Access all namespaces - should use preloaded data and get correct data per namespace + expectedUIDs := map[string]string{ + "default": "org1-ds", + "org-2": "org2-ds", + "org-3": "org3-ds", + } + + for _, ns := range []string{"default", "org-2", "org-3"} { + ctx := request.WithNamespace(context.Background(), ns) + idx := cached.Get(ctx) + require.NotNil(t, idx, "index for namespace %s should not be nil", ns) + assert.Equal(t, expectedUIDs[ns], idx.GetDefault().UID, "namespace %s should get correct datasource", ns) + } + + // The underlying provider should still have been called only 3 times (from preload) + assert.Equal(t, 3, underlying.callCount, + "access after preload should use cached data for all namespaces") +} + +// namespaceAwareProvider returns different datasources based on namespace +type namespaceAwareProvider struct { + datasourcesByNamespace map[string][]DataSourceInfo + callCount int +} + +func (p *namespaceAwareProvider) Index(ctx context.Context) *DatasourceIndex { + p.callCount++ + ns := request.NamespaceValue(ctx) + if ds, ok := p.datasourcesByNamespace[ns]; ok { + return NewDatasourceIndex(ds) + } + return NewDatasourceIndex(nil) +} + +// createNamespaceInfo creates a NamespaceInfo for testing +func createNamespaceInfo(orgID, stackID int64, value string) authlib.NamespaceInfo { + return authlib.NamespaceInfo{ + OrgID: orgID, + StackID: stackID, + Value: value, + } +} + +// Test DatasourceIndex functionality +func TestDatasourceIndex_Lookup(t *testing.T) { + datasources := []DataSourceInfo{ + {UID: "ds-uid-1", Type: "prometheus", Name: "Prometheus DS", Default: true, APIVersion: "v1"}, + {UID: "ds-uid-2", Type: "loki", Name: "Loki DS", Default: false, APIVersion: "v1"}, + } + idx := NewDatasourceIndex(datasources) + + t.Run("lookup by name", func(t *testing.T) { + ds := idx.Lookup("Prometheus DS") + require.NotNil(t, ds) + assert.Equal(t, "ds-uid-1", ds.UID) + }) + + t.Run("lookup by UID", func(t *testing.T) { + ds := idx.Lookup("ds-uid-2") + require.NotNil(t, ds) + assert.Equal(t, "Loki DS", ds.Name) + }) + + t.Run("lookup unknown returns nil", func(t *testing.T) { + ds := idx.Lookup("unknown") + assert.Nil(t, ds) + }) + + t.Run("get default", func(t *testing.T) { + ds := idx.GetDefault() + require.NotNil(t, ds) + assert.Equal(t, "ds-uid-1", ds.UID) + }) + + t.Run("lookup by UID directly", func(t *testing.T) { + ds := idx.LookupByUID("ds-uid-1") + require.NotNil(t, ds) + assert.Equal(t, "Prometheus DS", ds.Name) + }) + + t.Run("lookup by name directly", func(t *testing.T) { + ds := idx.LookupByName("Loki DS") + require.NotNil(t, ds) + assert.Equal(t, "ds-uid-2", ds.UID) + }) +} + +func TestDatasourceIndex_EmptyIndex(t *testing.T) { + idx := NewDatasourceIndex(nil) + + assert.Nil(t, idx.GetDefault()) + assert.Nil(t, idx.Lookup("anything")) + assert.Nil(t, idx.LookupByUID("anything")) + assert.Nil(t, idx.LookupByName("anything")) +} + +// TestCachedProvider_TTLExpiration verifies that cache expires after TTL +func TestCachedProvider_TTLExpiration(t *testing.T) { + datasources := []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + } + + underlying := newTestProvider(datasources) + // Use a very short TTL for testing + shortTTL := 50 * time.Millisecond + cached := newCachedProvider(underlying.get, defaultCacheSize, shortTTL) + + ctx := request.WithNamespace(context.Background(), "default") + + // First call - should call underlying provider + idx1 := cached.Get(ctx) + require.NotNil(t, idx1) + assert.Equal(t, int64(1), underlying.getCallCount(), "first call should invoke underlying provider") + + // Second call immediately - should use cache + idx2 := cached.Get(ctx) + require.NotNil(t, idx2) + assert.Equal(t, int64(1), underlying.getCallCount(), "second call should use cache") + + // Wait for TTL to expire + time.Sleep(shortTTL + 20*time.Millisecond) + + // Third call after TTL - should call underlying provider again + idx3 := cached.Get(ctx) + require.NotNil(t, idx3) + assert.Equal(t, int64(2), underlying.getCallCount(), + "after TTL expiration, underlying provider should be called again") +} + +// TestCachedProvider_ParallelNamespacesFetch verifies that different namespaces can fetch in parallel +func TestCachedProvider_ParallelNamespacesFetch(t *testing.T) { + // Create a blocking provider that tracks concurrent executions + provider := &blockingProvider{ + blockDuration: 100 * time.Millisecond, + datasources: []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + }, + } + cached := newCachedProvider(provider.get, defaultCacheSize, time.Minute) + + numNamespaces := 5 + var wg sync.WaitGroup + + // Launch fetches for different namespaces simultaneously + startTime := time.Now() + for i := 0; i < numNamespaces; i++ { + wg.Add(1) + namespace := fmt.Sprintf("org-%d", i+1) + go func(ns string) { + defer wg.Done() + ctx := request.WithNamespace(context.Background(), ns) + idx := cached.Get(ctx) + require.NotNil(t, idx) + }(namespace) + } + wg.Wait() + elapsed := time.Since(startTime) + + // Verify that all namespaces were called + assert.Equal(t, int64(numNamespaces), provider.callCount.Load()) + + // Verify max concurrent executions shows parallelism + maxConcurrent := provider.maxConcurrent.Load() + assert.Equal(t, int64(numNamespaces), maxConcurrent) + + // If all namespaces had to wait sequentially, it would take numNamespaces * blockDuration + // With parallelism, it should be much faster (close to just blockDuration) + sequentialTime := time.Duration(numNamespaces) * provider.blockDuration + assert.Less(t, elapsed, sequentialTime) +} + +// TestCachedProvider_SameNamespaceSerialFetch verifies that the same namespace doesn't fetch concurrently +func TestCachedProvider_SameNamespaceSerialFetch(t *testing.T) { + // Create a blocking provider that tracks concurrent executions + provider := &blockingProvider{ + blockDuration: 100 * time.Millisecond, + datasources: []DataSourceInfo{ + {UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true}, + }, + } + cached := newCachedProvider(provider.get, defaultCacheSize, time.Minute) + + numGoroutines := 10 + var wg sync.WaitGroup + + // Launch multiple fetches for the SAME namespace simultaneously + ctx := request.WithNamespace(context.Background(), "default") + for i := 0; i < numGoroutines; i++ { + wg.Add(1) + go func() { + defer wg.Done() + idx := cached.Get(ctx) + require.NotNil(t, idx) + }() + } + wg.Wait() + + // Max concurrent should be 1 since all goroutines are for the same namespace + maxConcurrent := provider.maxConcurrent.Load() + assert.Equal(t, int64(1), maxConcurrent) +} + +// blockingProvider is a test provider that simulates slow fetch operations +// and tracks concurrent executions +type blockingProvider struct { + blockDuration time.Duration + datasources []DataSourceInfo + callCount atomic.Int64 + currentActive atomic.Int64 + maxConcurrent atomic.Int64 +} + +func (p *blockingProvider) get(_ context.Context) any { + p.callCount.Add(1) + + // Track concurrent executions + current := p.currentActive.Add(1) + + // Update max concurrent if this is a new peak + for { + maxVal := p.maxConcurrent.Load() + if current <= maxVal { + break + } + if p.maxConcurrent.CompareAndSwap(maxVal, current) { + break + } + } + + // Simulate slow operation + time.Sleep(p.blockDuration) + + p.currentActive.Add(-1) + return p.datasources +} diff --git a/apps/dashboard/pkg/migration/schemaversion/datasource_utils.go b/apps/dashboard/pkg/migration/schemaversion/datasource_utils.go index 18bc2fc17c4..c7215495dc9 100644 --- a/apps/dashboard/pkg/migration/schemaversion/datasource_utils.go +++ b/apps/dashboard/pkg/migration/schemaversion/datasource_utils.go @@ -2,7 +2,6 @@ package schemaversion import ( "context" - "sync" "time" ) @@ -11,65 +10,41 @@ import ( // string names/UIDs to structured reference objects with uid, type, and apiVersion. // cachedIndexProvider wraps a DataSourceIndexProvider with time-based caching. -// This prevents multiple DB queries and index builds during operations that may call -// provider.Index() multiple times (e.g., dashboard conversions with many datasource lookups). -// The cache expires after 10 seconds, allowing it to be used as a long-lived singleton -// while still refreshing periodically. -// -// Thread-safe: Uses sync.RWMutex to guarantee safe concurrent access. type cachedIndexProvider struct { - provider DataSourceIndexProvider - mu sync.RWMutex - index *DatasourceIndex - cachedAt time.Time - cacheTTL time.Duration + *cachedProvider[*DatasourceIndex] } -// Index returns the cached index if it's still valid (< 10s old), otherwise rebuilds it. -// Uses RWMutex for efficient concurrent reads when cache is valid. +// Index returns the cached index if it's still valid (< TTL old), otherwise rebuilds it. func (p *cachedIndexProvider) Index(ctx context.Context) *DatasourceIndex { - // Fast path: check if cache is still valid using read lock - p.mu.RLock() - if p.index != nil && time.Since(p.cachedAt) < p.cacheTTL { - idx := p.index - p.mu.RUnlock() - return idx - } - p.mu.RUnlock() - - // Slow path: cache expired or not yet built, acquire write lock - p.mu.Lock() - defer p.mu.Unlock() - - // Double-check: another goroutine might have refreshed the cache - // while we were waiting for the write lock - if p.index != nil && time.Since(p.cachedAt) < p.cacheTTL { - return p.index - } - - // Rebuild the cache - p.index = p.provider.Index(ctx) - p.cachedAt = time.Now() - return p.index + return p.Get(ctx) } -// WrapIndexProviderWithCache wraps a provider to cache the index with a 10-second TTL. -// Useful for conversions or migrations that may call provider.Index() multiple times. -// The cache expires after 10 seconds, making it suitable for use as a long-lived singleton -// at the top level of dependency injection while still refreshing periodically. -// -// Example usage in dashboard conversion: -// -// cachedDsIndexProvider := schemaversion.WrapIndexProviderWithCache(dsIndexProvider) -// // Now all calls to cachedDsIndexProvider.Index(ctx) return the same cached index -// // for up to 10 seconds before refreshing -func WrapIndexProviderWithCache(provider DataSourceIndexProvider) DataSourceIndexProvider { - if provider == nil { - return nil +// cachedLibraryElementProvider wraps a LibraryElementIndexProvider with time-based caching. +type cachedLibraryElementProvider struct { + *cachedProvider[[]LibraryElementInfo] +} + +func (p *cachedLibraryElementProvider) GetLibraryElementInfo(ctx context.Context) []LibraryElementInfo { + return p.Get(ctx) +} + +// WrapIndexProviderWithCache wraps a DataSourceIndexProvider to cache indexes with a configurable TTL. +func WrapIndexProviderWithCache(provider DataSourceIndexProvider, cacheTTL time.Duration) DataSourceIndexProvider { + if provider == nil || cacheTTL <= 0 { + return provider } return &cachedIndexProvider{ - provider: provider, - cacheTTL: 10 * time.Second, + newCachedProvider[*DatasourceIndex](provider.Index, defaultCacheSize, cacheTTL), + } +} + +// WrapLibraryElementProviderWithCache wraps a LibraryElementIndexProvider to cache library elements with a configurable TTL. +func WrapLibraryElementProviderWithCache(provider LibraryElementIndexProvider, cacheTTL time.Duration) LibraryElementIndexProvider { + if provider == nil || cacheTTL <= 0 { + return provider + } + return &cachedLibraryElementProvider{ + newCachedProvider[[]LibraryElementInfo](provider.GetLibraryElementInfo, defaultCacheSize, cacheTTL), } } @@ -216,60 +191,3 @@ func MigrateDatasourceNameToRef(nameOrRef interface{}, options map[string]bool, return nil } - -// cachedLibraryElementProvider wraps a LibraryElementIndexProvider with time-based caching. -// This prevents multiple DB queries during operations that may call GetLibraryElementInfo() -// multiple times (e.g., dashboard conversions with many library panel lookups). -// The cache expires after 10 seconds, allowing it to be used as a long-lived singleton -// while still refreshing periodically. -// -// Thread-safe: Uses sync.RWMutex to guarantee safe concurrent access. -type cachedLibraryElementProvider struct { - provider LibraryElementIndexProvider - mu sync.RWMutex - elements []LibraryElementInfo - cachedAt time.Time - cacheTTL time.Duration -} - -// GetLibraryElementInfo returns the cached library elements if they're still valid (< 10s old), otherwise rebuilds the cache. -// Uses RWMutex for efficient concurrent reads when cache is valid. -func (p *cachedLibraryElementProvider) GetLibraryElementInfo(ctx context.Context) []LibraryElementInfo { - // Fast path: check if cache is still valid using read lock - p.mu.RLock() - if p.elements != nil && time.Since(p.cachedAt) < p.cacheTTL { - elements := p.elements - p.mu.RUnlock() - return elements - } - p.mu.RUnlock() - - // Slow path: cache expired or not yet built, acquire write lock - p.mu.Lock() - defer p.mu.Unlock() - - // Double-check: another goroutine might have refreshed the cache - // while we were waiting for the write lock - if p.elements != nil && time.Since(p.cachedAt) < p.cacheTTL { - return p.elements - } - - // Rebuild the cache - p.elements = p.provider.GetLibraryElementInfo(ctx) - p.cachedAt = time.Now() - return p.elements -} - -// WrapLibraryElementProviderWithCache wraps a provider to cache library elements with a 10-second TTL. -// Useful for conversions or migrations that may call GetLibraryElementInfo() multiple times. -// The cache expires after 10 seconds, making it suitable for use as a long-lived singleton -// at the top level of dependency injection while still refreshing periodically. -func WrapLibraryElementProviderWithCache(provider LibraryElementIndexProvider) LibraryElementIndexProvider { - if provider == nil { - return nil - } - return &cachedLibraryElementProvider{ - provider: provider, - cacheTTL: 10 * time.Second, - } -} diff --git a/apps/dashboard/pkg/migration/schemaversion/migration_utils.go b/apps/dashboard/pkg/migration/schemaversion/migration_utils.go index 64dfc61589e..d964fcaf513 100644 --- a/apps/dashboard/pkg/migration/schemaversion/migration_utils.go +++ b/apps/dashboard/pkg/migration/schemaversion/migration_utils.go @@ -102,3 +102,71 @@ func IsArray(value interface{}) bool { _, ok := value.([]interface{}) return ok } + +// AngularPanelMigrations maps deprecated Angular panel types to their modern equivalents. +// Used by both v0→v1 and v1→v2 conversions to ensure consistent migration behavior. +var AngularPanelMigrations = map[string]string{ + "table-old": "table", + "singlestat": "stat", + "grafana-singlestat-panel": "stat", + "grafana-piechart-panel": "piechart", + "grafana-worldmap-panel": "geomap", + "natel-discrete-panel": "state-timeline", +} + +// GetAngularPanelMigration checks if a panel type is an Angular panel and returns the new type to migrate to. +// Returns the new panel type if migration is needed, empty string otherwise. +// This handles both simple mappings and special cases like graph panel. +func GetAngularPanelMigration(panelType string, panel map[string]interface{}) string { + // Handle graph panel specially - it can migrate to different panel types + // based on xaxis.mode + if panelType == "graph" || panelType == "graphite" { + return GetGraphMigrationTarget(panel) + } + + // Check simple Angular panel mappings + if newType, isAngular := AngularPanelMigrations[panelType]; isAngular { + return newType + } + + return "" +} + +// GetGraphMigrationTarget determines the target panel type for graph panel migration. +// Graph panels can migrate to timeseries, barchart, bargauge, or histogram depending on xaxis.mode. +func GetGraphMigrationTarget(panel map[string]interface{}) string { + // Default to timeseries + newType := "timeseries" + + // Check xaxis mode for special cases + if xaxis, ok := panel["xaxis"].(map[string]interface{}); ok { + if mode, ok := xaxis["mode"].(string); ok { + switch mode { + case "series": + // Check legend values for bargauge vs barchart + if legend, ok := panel["legend"].(map[string]interface{}); ok { + if values, ok := legend["values"].(bool); ok && values { + newType = "bargauge" + } else { + newType = "barchart" + } + } else { + newType = "barchart" + } + case "histogram": + newType = "histogram" + } + } + } + + return newType +} + +// IsAngularPanelType checks if a panel type is a known Angular panel type. +func IsAngularPanelType(panelType string) bool { + if panelType == "graph" || panelType == "graphite" { + return true + } + _, isAngular := AngularPanelMigrations[panelType] + return isAngular +} diff --git a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/migrations/migrations.v42.json b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/migrations/migrations.v42.json index 89ce80876d2..6ff361f144e 100644 --- a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/migrations/migrations.v42.json +++ b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/migrations/migrations.v42.json @@ -290,6 +290,7 @@ } }, { + "content": "# Graph panel \u003e\u003e Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions", "datasource": { "type": "grafana-testdata-datasource" }, @@ -300,15 +301,7 @@ "y": 0 }, "id": 6, - "options": { - "code": { - "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" - }, + "mode": "markdown", "pluginVersion": "11.0.0-pre", "targets": [ { diff --git a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-canvas/canvas_kitchen_sink.v42.json b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-canvas/canvas_kitchen_sink.v42.json new file mode 100644 index 00000000000..cf4db2fb1b6 --- /dev/null +++ b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-canvas/canvas_kitchen_sink.v42.json @@ -0,0 +1,598 @@ +{ + "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" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "1": { + "color": "green", + "icon": "img/icons/unicons/check-circle.svg", + "index": 0, + "text": "Success" + }, + "2": { + "color": "orange", + "icon": "img/icons/unicons/exclamation-triangle.svg", + "index": 1, + "text": "Warning" + }, + "3": { + "color": "red", + "icon": "img/icons/unicons/times-circle.svg", + "index": 2, + "text": "Error" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text" + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "success" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "1": { + "color": "green", + "icon": "img/icons/unicons/check-circle.svg", + "index": 0, + "text": "Success" + } + }, + "type": "value" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "warning" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "2": { + "color": "orange", + "icon": "img/icons/unicons/exclamation-triangle.svg", + "index": 1, + "text": "Warning" + } + }, + "type": "value" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "error" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "3": { + "color": "red", + "icon": "img/icons/unicons/times-circle.svg", + "index": 2, + "text": "Error" + } + }, + "type": "value" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "unmapped" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "1": { + "color": "green", + "icon": "img/icons/unicons/check-circle.svg", + "index": 0, + "text": "Success" + }, + "2": { + "color": "orange", + "icon": "img/icons/unicons/exclamation-triangle.svg", + "index": 1, + "text": "Warning" + }, + "3": { + "color": "red", + "icon": "img/icons/unicons/times-circle.svg", + "index": 2, + "text": "Error" + } + }, + "type": "value" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "inlineEditing": true, + "root": { + "background": { + "color": { + "fixed": "transparent" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "elements": [ + { + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 16, + "text": { + "fixed": "Field-based Icons (from value mappings):", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Header", + "placement": { + "height": 40, + "left": 20, + "top": 10, + "width": 400 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "success", + "fixed": "green" + }, + "path": { + "field": "success", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Success Icon", + "placement": { + "height": 50, + "left": 50, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "success", + "fixed": "text" + }, + "size": 12, + "text": { + "field": "success", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Success Text", + "placement": { + "height": 25, + "left": 30, + "top": 115, + "width": 90 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "warning", + "fixed": "orange" + }, + "path": { + "field": "warning", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Warning Icon", + "placement": { + "height": 50, + "left": 180, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "warning", + "fixed": "text" + }, + "size": 12, + "text": { + "field": "warning", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Warning Text", + "placement": { + "height": 25, + "left": 160, + "top": 115, + "width": 90 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "error", + "fixed": "red" + }, + "path": { + "field": "error", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Error Icon", + "placement": { + "height": 50, + "left": 310, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "error", + "fixed": "text" + }, + "size": 12, + "text": { + "field": "error", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Error Text", + "placement": { + "height": 25, + "left": 290, + "top": 115, + "width": 90 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "unmapped", + "fixed": "#808080" + }, + "path": { + "field": "unmapped", + "fixed": "img/icons/unicons/question-circle.svg", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Unmapped Icon", + "placement": { + "height": 50, + "left": 440, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "unmapped", + "fixed": "text" + }, + "size": 12, + "text": { + "fixed": "No mapping (14)", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Unmapped Text", + "placement": { + "height": 25, + "left": 410, + "top": 115, + "width": 110 + }, + "type": "text" + }, + { + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 14, + "text": { + "fixed": "Fixed Relative Path:", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Relative Label", + "placement": { + "height": 30, + "left": 50, + "top": 170, + "width": 200 + }, + "type": "text" + }, + { + "config": { + "fill": { + "fixed": "blue" + }, + "path": { + "fixed": "img/icons/unicons/cloud.svg", + "mode": "fixed" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Relative Icon", + "placement": { + "height": 50, + "left": 260, + "top": 165, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 14, + "text": { + "fixed": "Fixed Absolute URL:", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Absolute Label", + "placement": { + "height": 30, + "left": 50, + "top": 240, + "width": 200 + }, + "type": "text" + }, + { + "config": { + "fill": { + "fixed": "purple" + }, + "path": { + "fixed": "https://grafana.com/static/assets/img/grafana_icon.svg", + "mode": "fixed" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Absolute Icon", + "placement": { + "height": 50, + "left": 260, + "top": 235, + "width": 50 + }, + "type": "icon" + } + ], + "name": "Canvas Root", + "placement": { + "height": 100, + "left": 0, + "top": 0, + "width": 100 + }, + "type": "frame" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "csvContent": "success\n1", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + }, + { + "csvContent": "warning\n2", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "B", + "scenarioId": "csv_content" + }, + { + "csvContent": "error\n3", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "C", + "scenarioId": "csv_content" + }, + { + "csvContent": "unmapped\n14", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "D", + "scenarioId": "csv_content" + } + ], + "title": "Various SVG icons", + "type": "canvas" + } + ], + "refresh": "", + "schemaVersion": 42, + "tags": [ + "canvas", + "icons", + "test", + "v2" + ], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Panel tests - Canvas - Kitchen sink", + "uid": "canvas-icon-fix-test-v2", + "weekStart": "" +} \ No newline at end of file diff --git a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests.v42.json b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests.v42.json index 92a865b0b10..635103053bf 100644 --- a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests.v42.json +++ b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests.v42.json @@ -628,6 +628,20 @@ } ], "title": "Only nulls and no user set min \u0026 max", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "number", + "targetField": "A-series" + } + ], + "fields": {} + } + } + ], "type": "gauge" }, { diff --git a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_new.v42.json b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_new.v42.json index 863d7b2a102..61f092d491e 100644 --- a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_new.v42.json +++ b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_new.v42.json @@ -71,14 +71,13 @@ "id": 1, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": false, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -150,14 +149,13 @@ "id": 4, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -229,14 +227,13 @@ "id": 3, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -305,96 +302,16 @@ "x": 12, "y": 1 }, - "id": 5, - "maxDataPoints": 20, - "options": { - "barWidthFactor": 0.4, - "effects": { - "barGlow": true, - "centerGlow": true, - "rounded": true, - "spotlight": true - }, - "gradient": "none", - "orientation": "auto", - "reduceOptions": { - "calcs": [ - "lastNotNull" - ], - "fields": "", - "values": false - }, - "segmentCount": 1, - "segmentSpacing": 0.3, - "shape": "circle", - "showThresholdLabels": false, - "showThresholdMarkers": false, - "sparkline": false - }, - "pluginVersion": "13.0.0-pre", - "targets": [ - { - "alias": "1", - "datasource": { - "type": "grafana-testdata-datasource" - }, - "max": 100, - "min": 1, - "noise": 22, - "refId": "A", - "scenarioId": "random_walk", - "spread": 22, - "startValue": 1 - } - ], - "title": "Spotlight", - "type": "radialbar" - }, - { - "datasource": { - "type": "grafana-testdata-datasource" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 4, - "x": 16, - "y": 1 - }, "id": 8, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -460,20 +377,19 @@ "gridPos": { "h": 6, "w": 4, - "x": 0, - "y": 7 + "x": 16, + "y": 1 }, "id": 22, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -539,20 +455,19 @@ "gridPos": { "h": 6, "w": 4, - "x": 4, - "y": 7 + "x": 20, + "y": 1 }, "id": 23, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -593,7 +508,7 @@ "h": 1, "w": 24, "x": 0, - "y": 13 + "y": 7 }, "id": 17, "panels": [], @@ -630,21 +545,20 @@ }, "gridPos": { "h": 6, - "w": 5, + "w": 4, "x": 0, - "y": 14 + "y": 8 }, "id": 18, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.1, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -709,21 +623,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 5, - "y": 14 + "w": 4, + "x": 4, + "y": 8 }, "id": 19, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.32, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -788,21 +701,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 10, - "y": 14 + "w": 4, + "x": 8, + "y": 8 }, "id": 20, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.57, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -867,21 +779,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 15, - "y": 14 + "w": 4, + "x": 12, + "y": 8 }, "id": 21, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.8, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -922,7 +833,7 @@ "h": 1, "w": 24, "x": 0, - "y": 20 + "y": 14 }, "id": 24, "panels": [], @@ -963,21 +874,20 @@ }, "gridPos": { "h": 6, - "w": 6, + "w": 4, "x": 0, - "y": 21 + "y": 15 }, "id": 25, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1042,21 +952,20 @@ }, "gridPos": { "h": 6, - "w": 6, - "x": 6, - "y": 21 + "w": 4, + "x": 4, + "y": 15 }, "id": 26, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1121,21 +1030,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 12, - "y": 21 + "w": 4, + "x": 8, + "y": 15 }, "id": 29, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1199,22 +1107,21 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 6, - "x": 0, - "y": 27 + "h": 6, + "w": 4, + "x": 12, + "y": 15 }, "id": 30, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1278,22 +1185,21 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 6, - "x": 6, - "y": 27 + "h": 6, + "w": 4, + "x": 16, + "y": 15 }, "id": 28, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1330,7 +1236,7 @@ "h": 1, "w": 24, "x": 0, - "y": 34 + "y": 21 }, "id": 31, "panels": [], @@ -1377,19 +1283,18 @@ "h": 10, "w": 7, "x": 0, - "y": 35 + "y": 22 }, "id": 32, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1460,19 +1365,18 @@ "h": 10, "w": 7, "x": 7, - "y": 35 + "y": 22 }, "id": 34, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1543,19 +1447,18 @@ "h": 10, "w": 6, "x": 14, - "y": 35 + "y": 22 }, "id": 33, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1592,7 +1495,7 @@ "h": 1, "w": 24, "x": 0, - "y": 45 + "y": 32 }, "id": 6, "panels": [], @@ -1603,7 +1506,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1634,21 +1536,21 @@ "h": 6, "w": 24, "x": 0, - "y": 46 + "y": 33 }, "id": 9, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "endpointMarker": "glow", "glow": "both", - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1662,8 +1564,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1671,7 +1572,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 98, "min": 5, "noise": 22, @@ -1689,7 +1589,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1720,21 +1619,20 @@ "h": 6, "w": 24, "x": 0, - "y": 52 + "y": 39 }, "id": 11, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1748,8 +1646,7 @@ "shape": "gauge", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": true, - "spotlight": true + "sparkline": true }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1757,7 +1654,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 98, "min": 5, "noise": 22, @@ -1777,7 +1673,7 @@ "h": 1, "w": 24, "x": 0, - "y": 58 + "y": 45 }, "id": 12, "panels": [], @@ -1788,7 +1684,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1820,21 +1715,20 @@ "h": 7, "w": 4, "x": 0, - "y": 59 + "y": 46 }, "id": 13, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1848,8 +1742,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1857,7 +1750,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 8, "min": 1, "noise": 2, @@ -1869,13 +1761,28 @@ } ], "title": "Active gateways", + "transformations": [ + { + "id": "calculateField", + "options": { + "mode": "unary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true, + "unary": { + "fieldName": "A-series", + "operator": "round" + } + } + } + ], "type": "radialbar" }, { "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1907,22 +1814,20 @@ "h": 7, "w": 5, "x": 4, - "y": 59 + "y": 46 }, "id": 14, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "sparkline": false, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -1936,8 +1841,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1945,7 +1849,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 12, "min": 1, "noise": 2, @@ -1957,13 +1860,28 @@ } ], "title": "Active pods", + "transformations": [ + { + "id": "calculateField", + "options": { + "mode": "unary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true, + "unary": { + "fieldName": "A-series", + "operator": "round" + } + } + } + ], "type": "radialbar" }, { "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1994,21 +1912,20 @@ "h": 7, "w": 5, "x": 9, - "y": 59 + "y": 46 }, "id": 15, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.84, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2022,8 +1939,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2031,7 +1947,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 100, "min": 10, "noise": 22, @@ -2049,7 +1964,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -2080,21 +1994,20 @@ "h": 7, "w": 6, "x": 14, - "y": 59 + "y": 46 }, "id": 16, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.66, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": [ @@ -2108,8 +2021,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2117,7 +2029,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 100, "min": 10, "noise": 22, @@ -2130,6 +2041,149 @@ ], "title": "Backend", "type": "radialbar" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 53 + }, + "id": 35, + "panels": [], + "title": "Empty data", + "type": "row" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 54 + }, + "id": 36, + "options": { + "barShape": "flat", + "barWidthFactor": 0.5, + "effects": { + "barGlow": false, + "centerGlow": false, + "gradient": true + }, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "segmentCount": 1, + "segmentSpacing": 0.3, + "shape": "gauge", + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sparkline": true + }, + "pluginVersion": "13.0.0-pre", + "targets": [ + { + "refId": "A", + "scenarioId": "random_walk", + "seriesCount": 0 + } + ], + "title": "Numeric, no series", + "type": "gauge" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 54 + }, + "id": 37, + "options": { + "barShape": "flat", + "barWidthFactor": 0.5, + "effects": { + "barGlow": false, + "centerGlow": false, + "gradient": true + }, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "segmentCount": 1, + "segmentSpacing": 0.3, + "shape": "gauge", + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sparkline": true + }, + "pluginVersion": "13.0.0-pre", + "targets": [ + { + "refId": "A", + "scenarioId": "logs" + } + ], + "title": "Non-numeric", + "type": "gauge" } ], "preload": false, diff --git a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_old_to_new.v42.json b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_old_to_new.v42.json index d4dd7980100..449955a9cc8 100644 --- a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_old_to_new.v42.json +++ b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-gauge/gauge_tests_old_to_new.v42.json @@ -485,6 +485,7 @@ }, "id": 12, "options": { + "displayName": "My gauge", "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", @@ -955,10 +956,8 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": [ diff --git a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-piechart/panel_test_piechart.v42.json b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-piechart/panel_test_piechart.v42.json index f705124be5b..5b07f246ae3 100644 --- a/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-piechart/panel_test_piechart.v42.json +++ b/apps/dashboard/pkg/migration/testdata/dev-dashboards-output/panel-piechart/panel_test_piechart.v42.json @@ -290,7 +290,7 @@ ], "legend": { "displayMode": "table", - "placement": "bottom", + "placement": "right", "showLegend": true, "values": [ "percent" @@ -304,7 +304,7 @@ "fields": "", "values": false }, - "showLegend": false, + "showLegend": true, "strokeWidth": 1, "text": {} }, @@ -323,6 +323,15 @@ } ], "title": "Percent", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "^Backend-(.*)$", + "renamePattern": "b-$1" + } + } + ], "type": "piechart" }, { @@ -366,7 +375,7 @@ ], "legend": { "displayMode": "table", - "placement": "bottom", + "placement": "right", "showLegend": true, "values": [ "value" @@ -380,7 +389,7 @@ "fields": "", "values": false }, - "showLegend": false, + "showLegend": true, "strokeWidth": 1, "text": {} }, @@ -399,6 +408,15 @@ } ], "title": "Value", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "(.*)", + "renamePattern": "$1-how-much-wood-could-a-woodchuck-chuck-if-a-woodchuck-could-chuck-wood" + } + } + ], "type": "piechart" }, { diff --git a/apps/dashboard/pkg/migration/testdata/input/v15.mimir_rollout_debugging.json b/apps/dashboard/pkg/migration/testdata/input/v15.mimir_rollout_debugging.json index dc0ca4e5845..1cc39838eab 100644 --- a/apps/dashboard/pkg/migration/testdata/input/v15.mimir_rollout_debugging.json +++ b/apps/dashboard/pkg/migration/testdata/input/v15.mimir_rollout_debugging.json @@ -654,7 +654,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": true, "label": "cluster", @@ -677,7 +679,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": false, "label": "namespace", diff --git a/apps/dashboard/pkg/migration/testdata/output/latest_version/v15.mimir_rollout_debugging.v42.json b/apps/dashboard/pkg/migration/testdata/output/latest_version/v15.mimir_rollout_debugging.v42.json index 6f507f5bc47..1195b2bec63 100644 --- a/apps/dashboard/pkg/migration/testdata/output/latest_version/v15.mimir_rollout_debugging.v42.json +++ b/apps/dashboard/pkg/migration/testdata/output/latest_version/v15.mimir_rollout_debugging.v42.json @@ -737,7 +737,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": true, "label": "cluster", @@ -758,7 +760,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": false, "label": "namespace", diff --git a/apps/dashboard/pkg/migration/testdata/output/single_version/v15.mimir_rollout_debugging.v15.json b/apps/dashboard/pkg/migration/testdata/output/single_version/v15.mimir_rollout_debugging.v15.json index dd9ec62ed85..30186560450 100644 --- a/apps/dashboard/pkg/migration/testdata/output/single_version/v15.mimir_rollout_debugging.v15.json +++ b/apps/dashboard/pkg/migration/testdata/output/single_version/v15.mimir_rollout_debugging.v15.json @@ -717,7 +717,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": true, "label": "cluster", @@ -739,7 +741,9 @@ "text": "prod", "value": "prod" }, - "datasource": "$datasource", + "datasource": { + "uid": "$datasource" + }, "hide": 0, "includeAll": false, "label": "namespace", diff --git a/apps/example/go.mod b/apps/example/go.mod index d63d23be302..f2afba81283 100644 --- a/apps/example/go.mod +++ b/apps/example/go.mod @@ -3,17 +3,17 @@ module github.com/grafana/grafana/apps/example go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251017153501-8512b219c5fe - k8s.io/apimachinery v0.34.2 - k8s.io/apiserver v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/apimachinery v0.34.3 + k8s.io/apiserver v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -24,13 +24,23 @@ require ( github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -42,7 +52,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -56,43 +66,43 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/example/go.sum b/apps/example/go.sum index 70c83a9fe37..c5110f46829 100644 --- a/apps/example/go.sum +++ b/apps/example/go.sum @@ -1,7 +1,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -25,14 +25,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -41,8 +67,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -56,10 +82,10 @@ github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGr github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4/go.mod h1:qeWYbnWzaYGl88JlL9+DsP1GT2Cudm58rLtx13fKZdw= 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/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251017153501-8512b219c5fe h1:pPoFj2bQKDBg5EyEdOU+Jn+0hQN+M775Qihk73RbdSs= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251017153501-8512b219c5fe/go.mod h1:zn/yoxKpWA2KUsxOhQbSbL8OCkF2JNLpSEHs+hQYvdM= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= @@ -83,8 +109,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -116,10 +142,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -134,30 +160,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -175,34 +201,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -211,41 +237,41 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/example/kinds/manifest.cue b/apps/example/kinds/manifest.cue index 934d419623d..65947eaa151 100644 --- a/apps/example/kinds/manifest.cue +++ b/apps/example/kinds/manifest.cue @@ -34,7 +34,7 @@ manifest: { v0alpha1: { kinds: [examplev0alpha1] - // This is explicitly set to false to keep the example app disabled by default. + // This is explicitly set to false to keep the example app disabled by default. // It can be enabled via conf overrides, or by setting this value to true and regenerating. served: false } @@ -48,14 +48,14 @@ v1alpha1: { // served indicates whether this particular version is served by the API server. // served should be set to false before a version is removed from the manifest entirely. // served defaults to true if not present. - // This is explicitly set to false to keep the example app disabled by default. + // This is explicitly set to false to keep the example app disabled by default. // It can be enabled via conf overrides, or by setting this value to true and regenerating. served: false // routes contains resource routes for the version, which are split into 'namespaced' and 'cluster' scoped routes. // This allows you to add additional non-storage- and non-kind- based handlers for your app. // These should only be used if the behavior cannot be accomplished by reconciliation on storage events or subresource routes on a kind. routes: { - // namespaced contains namespace-scoped resource routes for the version, + // namespaced contains namespace-scoped resource routes for the version, // which are exposed as HTTP handlers on '/namespaces//'. namespaced: { "/something": { @@ -72,7 +72,7 @@ v1alpha1: { } } } - // cluster contains cluster-scoped resource routes for the version, + // cluster contains cluster-scoped resource routes for the version, // which are exposed as HTTP handlers on '/'. cluster: { "/other": { @@ -113,4 +113,4 @@ v1alpha1: { enabled: true } } -} \ No newline at end of file +} diff --git a/apps/folder/go.mod b/apps/folder/go.mod index 476c6949c73..9a673364f89 100644 --- a/apps/folder/go.mod +++ b/apps/folder/go.mod @@ -3,10 +3,10 @@ module github.com/grafana/grafana/apps/folder go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 + github.com/grafana/grafana-app-sdk v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( @@ -17,19 +17,29 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.48.3 // indirect + github.com/google/gnostic-models v0.7.1 // indirect + github.com/grafana/grafana-app-sdk/logging v0.48.7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -40,29 +50,29 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.11.1 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/folder/go.sum b/apps/folder/go.sum index d8454185267..3b414d3e3fe 100644 --- a/apps/folder/go.sum +++ b/apps/folder/go.sum @@ -14,29 +14,55 @@ github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e h1:BTKk7LHuG1kmAkucwTA7DuMbKpKvJTKrGdBmUNO4dfQ= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250514132646-acbc7b54ed9e/go.mod h1:IA4SOwun8QyST9c5UNs/fN37XL6boXXDvRYFcFwbipg= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -58,8 +84,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -76,8 +102,6 @@ github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletI github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -85,10 +109,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -101,16 +125,16 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= @@ -126,24 +150,24 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -154,31 +178,31 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/iam/go.mod b/apps/iam/go.mod index 474779e0efe..e35a733d350 100644 --- a/apps/iam/go.mod +++ b/apps/iam/go.mod @@ -24,8 +24,6 @@ replace github.com/grafana/grafana/apps/alerting/historian => ../alerting/histor replace github.com/grafana/grafana/apps/correlations => ../correlations -replace github.com/grafana/grafana/apps/investigations => ../investigations - replace github.com/grafana/grafana/apps/logsdrilldown => ../logsdrilldown replace github.com/grafana/grafana/apps/playlist => ../playlist @@ -52,19 +50,19 @@ replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-aler require ( github.com/grafana/grafana v0.0.0-00010101000000-000000000000 - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana/apps/folder v0.0.0 github.com/grafana/grafana/pkg/apimachinery v0.0.0 github.com/prometheus/client_golang v1.23.2 - go.opentelemetry.io/otel v1.38.0 - go.opentelemetry.io/otel/trace v1.38.0 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + go.opentelemetry.io/otel v1.39.0 + go.opentelemetry.io/otel/trace v1.39.0 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( - cel.dev/expr v0.24.0 // indirect + cel.dev/expr v0.25.1 // indirect cloud.google.com/go v0.121.4 // indirect cloud.google.com/go/auth v0.16.3 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect @@ -89,6 +87,7 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/IBM/pgxpoolprometheus v1.1.2 // indirect + github.com/Machiel/slugify v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect @@ -105,25 +104,25 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // 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-v2 v1.39.1 // indirect + github.com/aws/aws-sdk-go-v2 v1.40.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect - github.com/aws/aws-sdk-go-v2/config v1.31.10 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.8 // indirect + github.com/aws/aws-sdk-go-v2/config v1.31.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84 // 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.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 // 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/accept-encoding v1.13.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.8 // 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/s3shared v1.18.17 // indirect github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.29.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 // indirect - github.com/aws/smithy-go v1.23.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // indirect + github.com/aws/smithy-go v1.23.2 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect github.com/benbjohnson/clock v1.3.5 // indirect @@ -131,7 +130,7 @@ require ( github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bluele/gcache v0.0.2 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/bufbuild/protocompile v0.14.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bwmarrin/snowflake v0.3.0 // indirect @@ -143,7 +142,7 @@ require ( github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f // indirect github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dennwc/varint v1.0.0 // indirect github.com/dgraph-io/badger/v4 v4.7.0 // indirect @@ -178,22 +177,24 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.24.0 // indirect github.com/go-openapi/errors v0.22.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/loads v0.23.1 // indirect github.com/go-openapi/runtime v0.28.0 // indirect github.com/go-openapi/spec v0.22.0 // indirect github.com/go-openapi/strfmt v0.24.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/conv v0.25.1 // indirect - github.com/go-openapi/swag/fileutils v0.25.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect - github.com/go-openapi/swag/jsonutils v0.25.1 // indirect - github.com/go-openapi/swag/loading v0.25.1 // indirect - github.com/go-openapi/swag/mangling v0.25.1 // indirect - github.com/go-openapi/swag/stringutils v0.25.1 // indirect - github.com/go-openapi/swag/typeutils v0.25.1 // indirect - github.com/go-openapi/swag/yamlutils v0.25.1 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-openapi/validate v0.25.0 // indirect github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/go-stack/stack v1.8.1 // indirect @@ -212,7 +213,7 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/cel-go v0.26.1 // indirect github.com/google/flatbuffers v25.2.10+incompatible // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/s2a-go v0.1.9 // indirect @@ -221,12 +222,12 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/googleapis/gax-go/v2 v2.15.0 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba // indirect + github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f // indirect github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect - github.com/grafana/grafana-aws-sdk v1.3.0 // indirect + github.com/grafana/grafana-aws-sdk v1.4.2 // indirect github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 // indirect github.com/grafana/grafana-plugin-sdk-go v0.284.0 // indirect github.com/grafana/grafana/apps/dashboard v0.0.0 // indirect @@ -239,7 +240,7 @@ require ( github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grafana/sqlds/v4 v4.2.7 // indirect + github.com/grafana/sqlds/v5 v5.0.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.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 @@ -285,7 +286,7 @@ require ( github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lestrrat-go/strftime v1.0.4 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -339,10 +340,10 @@ require ( github.com/pressly/goose/v3 v3.26.0 // indirect github.com/prometheus/alertmanager v0.28.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect + github.com/prometheus/common v0.67.4 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.14.0 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/prometheus/prometheus v0.303.1 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/redis/go-redis/v9 v9.14.0 // indirect @@ -359,7 +360,7 @@ require ( github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect github.com/spf13/cast v1.10.0 // indirect - github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/spf13/viper v1.21.0 // indirect github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect @@ -373,20 +374,20 @@ require ( github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.etcd.io/etcd/api/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/v3 v3.6.4 // indirect + go.etcd.io/etcd/api/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/v3 v3.6.6 // indirect go.mongodb.org/mongo-driver v1.17.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/bridges/prometheus v0.61.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect @@ -394,18 +395,18 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.37.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.12.2 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.6.0 // indirect @@ -414,30 +415,30 @@ require ( go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect gocloud.dev v0.43.0 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect golang.org/x/tools/godoc v0.1.0-deprecated // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/api v0.242.0 // indirect google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/mail.v2 v2.3.1 // indirect @@ -446,20 +447,20 @@ require ( gopkg.in/telebot.v3 v3.3.8 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect - k8s.io/component-base v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect + k8s.io/component-base v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kms v0.34.2 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect + k8s.io/kms v0.34.3 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect modernc.org/libc v1.66.10 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect modernc.org/sqlite v1.40.1 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/iam/go.sum b/apps/iam/go.sum index 7f2fd8f462f..063696e3d5a 100644 --- a/apps/iam/go.sum +++ b/apps/iam/go.sum @@ -2,8 +2,8 @@ buf.build/gen/go/parca-dev/parca/connectrpc/go v1.18.1-20250703125925-3f0fcf4bff buf.build/gen/go/parca-dev/parca/connectrpc/go v1.18.1-20250703125925-3f0fcf4bff96.1/go.mod h1:pjl83IqpNF7Lm/lOPMLQ5IIfCg+yTu2A9OgYTcEncCs= buf.build/gen/go/parca-dev/parca/protocolbuffers/go v1.36.2-20250703125925-3f0fcf4bff96.1 h1:9nqE/pDc/HXAXiD5pZncPywjAzWgKuBkFFYgdK2lVU8= buf.build/gen/go/parca-dev/parca/protocolbuffers/go v1.36.2-20250703125925-3f0fcf4bff96.1/go.mod h1:1M7nlq2ljfzb95x9LaA2j1gYIvDkVZii58mGvTa9ExM= -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= @@ -82,10 +82,10 @@ cloud.google.com/go/storage v1.55.0 h1:NESjdAToN9u1tmhVqhXCaCwYBuvEhZLLv0gBr+2zn cloud.google.com/go/storage v1.55.0/go.mod h1:ztSmTTwzsdXe5syLVS0YsbFxXuvEmEyZj7v7zChEmuY= cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4= cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI= -connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw= -connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= -cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 h1:R5wwEcbEZSBmeyg91MJZTxfd7WpBo2jPof3AYjRbxwY= -cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= +connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14= +connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819 h1:Zh+Ur3OsoWpvALHPLT45nOekHkgOt+IOfutBbPqM17I= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819/go.mod h1:WjmQxb+W6nVNCgj8nXrF24lIz95AHwnSl36tpjDZSU8= cuelang.org/go v0.11.1 h1:pV+49MX1mmvDm8Qh3Za3M786cty8VKPWzQ1Ho4gZRP0= cuelang.org/go v0.11.1/go.mod h1:PBY6XvPUswPPJ2inpvUozP9mebDVTXaeehQikhZPBz0= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= @@ -150,6 +150,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= +github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/FZambia/eagle v0.2.0 h1:1kQaZpJvbkvAXFRE/9K2ucBMuVqo+E29EMLYB74hIis= github.com/FZambia/eagle v0.2.0/go.mod h1:LKMYBwGYhao5sJI0TppvQ4SvvldFj9gITxrl8NvGwG0= @@ -165,6 +167,8 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/IBM/pgxpoolprometheus v1.1.2 h1:sHJwxoL5Lw4R79Zt+H4Uj1zZ4iqXJLdk7XDE7TPs97U= 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/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -234,24 +238,24 @@ 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.55.7 h1:UJrkFq7es5CShfBwlWAC8DA077vp8PyVbQd3lqLiztE= github.com/aws/aws-sdk-go v1.55.7/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.39.1 h1:fWZhGAwVRK/fAN2tmt7ilH4PPAE11rDj7HytrmbZ2FE= -github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc= +github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= 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/config v1.31.10 h1:7LllDZAegXU3yk41mwM6KcPu0wmjKGQB1bg99bNdQm4= -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.14 h1:TxkI7QI+sFkTItN/6cJuMZEIVMFXeu2dI1ZffkXngKI= -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.8 h1:gLD09eaJUdiszm7vd1btiQUYE0Hj+0I2b8AS+75z9AY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.8/go.mod h1:4RW3oMPt1POR74qVOC4SbubxAwdP4pCT0nSw3jycOU4= +github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y= +github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c= +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.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= +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.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= 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/internal/configsources v1.4.8 h1:6bgAZgRyT4RoFWhxS+aoGMFyE0cD1bSzFnEEi4bFPGI= -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.8 h1:HhJYoES3zOz34yWEpGENqJvRVPqpmJyR3+AFg9ybhdY= -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.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -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/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I= +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/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY= +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/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= 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/service/cloudwatch v1.45.3 h1:Nn3qce+OHZuMj/edx4its32uxedAmquCDxtZkrdeiD4= @@ -260,12 +264,12 @@ github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.51.0 h1:e5cbPZYTIY2nUEFie github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.51.0/go.mod h1:UseIHRfrm7PqeZo6fcTb6FUCXzCnh1KJbQbmOfxArGM= github.com/aws/aws-sdk-go-v2/service/ec2 v1.225.2 h1:IfMb3Ar8xEaWjgH/zeVHYD8izwJdQgRP5mKCTDt4GNk= github.com/aws/aws-sdk-go-v2/service/ec2 v1.225.2/go.mod h1:35jGWx7ECvCwTsApqicFYzZ7JFEnBc6oHUuOQ3xIS54= -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.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +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.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= 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/presigned-url v1.13.8 h1:M6JI2aGFEzYxsF6CXIuRBnkge9Wf9a2xU39rNeXgu10= -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/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= +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/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/kms v1.41.2 h1:zJeUxFP7+XP52u23vrp4zMcVhShTWbNO8dHV6xCSvFo= @@ -276,14 +280,16 @@ github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.26.6 h1:Pwbxovp github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.26.6/go.mod h1:Z4xLt5mXspLKjBV92i165wAJ/3T6TIv4n7RtIS8pWV0= 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/sso v1.29.4 h1:FTdEN9dtWPB0EOURNtDPmwGp6GGvMqRJCAihkSl/1No= -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.0 h1:I7ghctfGXrscr7r1Ga/mDqSJKm7Fkpl5Mwq79Z+rZqU= -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.38.5 h1:+LVB0xBqEgjQoqr9bGZbRzvg212B0f17JdflleJRNR4= -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.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= -github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1 h1:w6a0H79HrHf3lr+zrw+pSzR5B+caiQFAKiNHlrUcnoc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1/go.mod h1:c6Vg0BRiU7v0MVhHupw90RyL120QBwAMLbDCzptGeMk= +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.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= +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.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= +github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= +github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/axiomhq/hyperloglog v0.0.0-20240507144631-af9851f82b27 h1:60m4tnanN1ctzIu4V3bfCNJ39BiOPSm1gHFlFjTkRE0= github.com/axiomhq/hyperloglog v0.0.0-20240507144631-af9851f82b27/go.mod h1:k08r+Yj1PRAmuayFiRK6MYuR5Ve4IuZtTfxErMIh0+c= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= @@ -356,8 +362,8 @@ github.com/blugelabs/ice v1.0.0/go.mod h1:gNfFPk5zM+yxJROhthxhVQYjpBO9amuxWXJQ2L github.com/blugelabs/ice/v2 v2.0.1 h1:mzHbntLjk2v7eDRgoXCgzOsPKN1Tenu9Svo6l9cTLS4= github.com/blugelabs/ice/v2 v2.0.1/go.mod h1:QxAWSPNwZwsIqS25c3lbIPFQrVvT1sphf5x5DfMLH5M= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -377,10 +383,10 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/centrifugal/centrifuge v0.37.2 h1:rerQNvDfYN2FZEkVtb/hvGV7SIrJfEQrKF3MaE8GDlo= -github.com/centrifugal/centrifuge v0.37.2/go.mod h1:aj4iRJGhzi3SlL8iUtVezxway1Xf8g+hmNQkLLO7sS8= -github.com/centrifugal/protocol v0.16.2 h1:KoIHgDeX1fFxyxQoKW+6E8ZTCf5mwGm8JyGoJ5NBMbQ= -github.com/centrifugal/protocol v0.16.2/go.mod h1:Q7OpS/8HMXDnL7f9DpNx24IhG96MP88WPpVTTCdrokI= +github.com/centrifugal/centrifuge v0.38.0 h1:UJTowwc5lSwnpvd3vbrTseODbU7osSggN67RTrJ8EfQ= +github.com/centrifugal/centrifuge v0.38.0/go.mod h1:rcZLARnO5GXOeE9qG7iIPMvERxESespqkSX4cGLCAzo= +github.com/centrifugal/protocol v0.17.0 h1:hD0WczyiG7zrVJcgkQsd5/nhfFXt0Y04SJHV2Z7B1rg= +github.com/centrifugal/protocol v0.17.0/go.mod h1:9MdiYyjw5Bw1+d5Sp4Y0NK+qiuTNyd88nrHJsUUh8k4= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -426,8 +432,8 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= @@ -499,8 +505,8 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= -github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= +github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84= github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= @@ -508,8 +514,8 @@ github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY= -github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/proto v1.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I= +github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -595,10 +601,10 @@ github.com/go-openapi/analysis v0.24.0 h1:vE/VFFkICKyYuTWYnplQ+aVr45vlG6NcZKC7Bd github.com/go-openapi/analysis v0.24.0/go.mod h1:GLyoJA+bvmGGaHgpfeDh8ldpGo69fAJg7eeMDMRCIrw= github.com/go-openapi/errors v0.22.3 h1:k6Hxa5Jg1TUyZnOwV2Lh81j8ayNw5VVYLvKrp4zFKFs= github.com/go-openapi/errors v0.22.3/go.mod h1:+WvbaBBULWCOna//9B9TbLNGSFOfF8lY9dw4hGiEiKQ= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/loads v0.23.1 h1:H8A0dX2KDHxDzc797h0+uiCZ5kwE2+VojaQVaTlXvS0= github.com/go-openapi/loads v0.23.1/go.mod h1:hZSXkyACCWzWPQqizAv/Ye0yhi2zzHwMmoXQ6YQml44= github.com/go-openapi/runtime v0.28.0 h1:gpPPmWSNGo214l6n8hzdXYhPuJcGtziTOgUpvsFWGIQ= @@ -607,28 +613,36 @@ github.com/go-openapi/spec v0.22.0 h1:xT/EsX4frL3U09QviRIZXvkh80yibxQmtoEvyqug0T github.com/go-openapi/spec v0.22.0/go.mod h1:K0FhKxkez8YNS94XzF8YKEMULbFrRw4m15i2YUht4L0= github.com/go-openapi/strfmt v0.24.0 h1:dDsopqbI3wrrlIzeXRbqMihRNnjzGC+ez4NQaAAJLuc= github.com/go-openapi/strfmt v0.24.0/go.mod h1:Lnn1Bk9rZjXxU9VMADbEEOo7D7CDyKGLsSKekhFr7s4= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0= -github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs= -github.com/go-openapi/swag/fileutils v0.25.1 h1:rSRXapjQequt7kqalKXdcpIegIShhTPXx7yw0kek2uU= -github.com/go-openapi/swag/fileutils v0.25.1/go.mod h1:+NXtt5xNZZqmpIpjqcujqojGFek9/w55b3ecmOdtg8M= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= -github.com/go-openapi/swag/jsonutils v0.25.1 h1:AihLHaD0brrkJoMqEZOBNzTLnk81Kg9cWr+SPtxtgl8= -github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1 h1:DSQGcdB6G0N9c/KhtpYc71PzzGEIc/fZ1no35x4/XBY= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1/go.mod h1:kjmweouyPwRUEYMSrbAidoLMGeJ5p6zdHi9BgZiqmsg= -github.com/go-openapi/swag/loading v0.25.1 h1:6OruqzjWoJyanZOim58iG2vj934TysYVptyaoXS24kw= -github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc= -github.com/go-openapi/swag/mangling v0.25.1 h1:XzILnLzhZPZNtmxKaz/2xIGPQsBsvmCjrJOWGNz/ync= -github.com/go-openapi/swag/mangling v0.25.1/go.mod h1:CdiMQ6pnfAgyQGSOIYnZkXvqhnnwOn997uXZMAd/7mQ= -github.com/go-openapi/swag/stringutils v0.25.1 h1:Xasqgjvk30eUe8VKdmyzKtjkVjeiXx1Iz0zDfMNpPbw= -github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg= -github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3I3ysiFZqukA= -github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= -github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk= -github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-openapi/validate v0.25.0 h1:JD9eGX81hDTjoY3WOzh6WqxVBVl7xjsLnvDo1GL5WPU= github.com/go-openapi/validate v0.25.0/go.mod h1:SUY7vKrN5FiwK6LyvSwKjDfLNirSfWwHNgxd2l29Mmw= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -735,8 +749,10 @@ github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ= github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic v0.7.1 h1:t5Kc7j/8kYr8t2u11rykRrPPovlEMG4+xdc/SpekATs= +github.com/google/gnostic v0.7.1/go.mod h1:KSw6sxnxEBFM8jLPfJd46xZP+yQcfE8XkiqfZx5zR28= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -817,8 +833,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= 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/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba h1:psKWNETD5nGxmFAlqnWsXoRyUwSa2GHNEMSEDKGKfQ4= -github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f h1:Br4SaUL3dnVopKKNhDavCLgehw60jdtl/sIxdfzmVts= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f/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/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg= github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGrHj3GdFbvsMzUT7eusgii9PKf9L1ZaXDDbY= @@ -835,12 +851,12 @@ github.com/grafana/gofpdf v0.0.0-20250307124105-3b9c5d35577f h1:5xkjl5Y/j2QefJKO github.com/grafana/gofpdf v0.0.0-20250307124105-3b9c5d35577f/go.mod h1:+O5QxOwwgP10jedZHapzXY+IPKTnzHBtIs5UUb9G+kI= github.com/grafana/gomemcache v0.0.0-20250828162811-a96f6acee2fe h1:q+QaVANzNZxvTovycpQvDTfsNZ2rHh4XIIaccMnrIR4= github.com/grafana/gomemcache v0.0.0-20250828162811-a96f6acee2fe/go.mod h1:j/s0jkda4UXTemDs7Pgw/vMT06alWc42CHisvYac0qw= -github.com/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= -github.com/grafana/grafana-aws-sdk v1.3.0 h1:/bfJzP93rCel1GbWoRSq0oUo424MZXt8jAp2BK9w8tM= -github.com/grafana/grafana-aws-sdk v1.3.0/go.mod h1:VGycF0JkCGKND2O5je1ucOqPJ0ZNhZYzV3c2bNBAaGk= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= +github.com/grafana/grafana-aws-sdk v1.4.2 h1:GrUEoLbs46r8rG/GZL4L2b63Bo+rkIYKdtCT7kT5KkM= +github.com/grafana/grafana-aws-sdk v1.4.2/go.mod h1:1qnZdYs6gQzxxF0dDodaE7Rn9fiMzuhwvtaAZ7ySnhY= 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-cloud-migration-snapshot v1.9.0 h1:JOzchPgptwJdruYoed7x28lFDwhzs7kssResYsnC0iI= @@ -853,6 +869,8 @@ github.com/grafana/grafana-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad github.com/grafana/grafana-plugin-sdk-go v0.284.0/go.mod h1:lHPniaSxq3SL5MxDIPy04TYB1jnTp/ivkYO+xn5Rz3E= github.com/grafana/grafana/apps/example v0.0.0-20251027162426-edef69fdc82b h1:6Bo65etvjQ4tStkaA5+N3A3ENbO4UAWj53TxF6g2Hdk= github.com/grafana/grafana/apps/example v0.0.0-20251027162426-edef69fdc82b/go.mod h1:6+wASOCN8LWt6FJ8dc0oODUBIEY5XHaE6ABi8g0mR+k= +github.com/grafana/grafana/apps/quotas v0.0.0-20251209183543-1013d74f13f2 h1:rDPMdshj3QMvpXn+wK4T8awF9n2sd8i4YRiGqX2xTvg= +github.com/grafana/grafana/apps/quotas v0.0.0-20251209183543-1013d74f13f2/go.mod h1:M7bV60iRB61y0ISPG1HX/oNLZtlh0ZF22rUYwNkAKjo= github.com/grafana/grafana/pkg/promlib v0.0.8 h1:VUWsqttdf0wMI4j9OX9oNrykguQpZcruudDAFpJJVw0= github.com/grafana/grafana/pkg/promlib v0.0.8/go.mod h1:U1ezG/MGaEPoThqsr3lymMPN5yIPdVTJnDZ+wcXT+ao= github.com/grafana/grafana/pkg/semconv v0.0.0-20250804150913-990f1c69ecc2 h1:A65jWgLk4Re28gIuZcpC0aTh71JZ0ey89hKGE9h543s= @@ -871,12 +889,12 @@ github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604 github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU= github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= -github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae h1:35W3Wjp9KWnSoV/DuymmyIj5aHE0CYlDQ5m2KeXUPAc= -github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae/go.mod h1:6CJ1uXmLZ13ufpO9xE4pST+DyaBt0uszzrV0YnoaVLQ= +github.com/grafana/pyroscope/api v1.2.1-0.20251118081820-ace37f973a0f h1:fTlIj5n4x5dU63XHItug7GLjtnaeJdPqBlqg4zlABq0= +github.com/grafana/pyroscope/api v1.2.1-0.20251118081820-ace37f973a0f/go.mod h1:VBNcIhunCZsJ3/mcYx+j7uFf0P/108eiWa+8+Z9ll3o= 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/sqlds/v4 v4.2.7 h1:sFQhsS7DBakNMdxa++yOfJ9BVvkZwFJ0B95o57K0/XA= -github.com/grafana/sqlds/v4 v4.2.7/go.mod h1:BQRjUG8rOqrBI4NAaeoWrIMuoNgfi8bdhCJ+5cgEfLU= +github.com/grafana/sqlds/v5 v5.0.3 h1:+yUMUxfa0WANQsmS9xtTFSRX1Q55Iv1B9EjlrW4VlBU= +github.com/grafana/sqlds/v5 v5.0.3/go.mod h1:GKeTTiC+GeR1X0z3f0Iee+hZnNgN62uQpj5XVMx5Uew= github.com/grafana/tempo v1.5.1-0.20250529124718-87c2dc380cec h1:wnzJov9RhSHGaTYGzTygL4qq986fLen8xSqnQgaMd28= github.com/grafana/tempo v1.5.1-0.20250529124718-87c2dc380cec/go.mod h1:j1IY7J2rUz7TcTjFVVx6HCpyTlYOJPtXuGRZ7sI+vSo= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= @@ -1100,8 +1118,8 @@ github.com/madflojo/testcerts v1.4.0/go.mod h1:MW8sh39gLnkKh4K0Nc55AyHEDl9l/FBLD github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 h1:hQWBtNqRYrI7CWIaUSXXtNKR90KzcUA5uiuxFVWw7sU= github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0= github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= @@ -1349,8 +1367,8 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg= @@ -1362,23 +1380,25 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/prometheus/prometheus v0.303.1 h1:He/2jRE6sB23Ew38AIoR1WRR3fCMgPlJA2E0obD2WSY= github.com/prometheus/prometheus v0.303.1/go.mod h1:WEq2ogBPZoLjj9x5K67VEk7ECR0nRD9XCjaOt1lsYck= github.com/prometheus/sigv4 v0.1.2 h1:R7570f8AoM5YnTUPFm3mjZH5q2k4D+I/phCWvZ4PXG8= github.com/prometheus/sigv4 v0.1.2/go.mod h1:GF9fwrvLgkQwDdQ5BXeV9XUSCH/IPNqzvAoaohfjqMU= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b h1:fPVI9E6QNFYI0Ph3XpKUDrcAvbCifHvqYJcntFLPog8= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/puzpuzpuz/xsync/v4 v4.2.0 h1:dlxm77dZj2c3rxq0/XNvvUKISAmovoXF4a4qM6Wvkr0= github.com/puzpuzpuz/xsync/v4 v4.2.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= +github.com/quagmt/udecimal v1.9.0 h1:TLuZiFeg0HhS6X8VDa78Y6XTaitZZfh+z5q4SXMzpDQ= +github.com/quagmt/udecimal v1.9.0/go.mod h1:ScmJ/xTGZcEoYiyMMzgDLn79PEJHcMBiJ4NNRT3FirA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE= github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -github.com/redis/rueidis v1.0.64 h1:XqgbueDuNV3qFdVdQwAHJl1uNt90zUuAJuzqjH4cw6Y= -github.com/redis/rueidis v1.0.64/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA= +github.com/redis/rueidis v1.0.68 h1:gept0E45JGxVigWb3zoWHvxEc4IOC7kc4V/4XvN8eG8= +github.com/redis/rueidis v1.0.68/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -1416,8 +1436,8 @@ github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3 h1:/4/IJi5iyTdh6mqOUaASW148HQpujYiHl0Wl78dSOSc= github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3/go.mod h1:aJIMhRsunltJR926EB2MUg8qHemFQDreSB33pyto2Ps= -github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs= -github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c= +github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE= +github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= @@ -1444,8 +1464,8 @@ github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8 github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -1519,8 +1539,8 @@ github.com/wk8/go-ordered-map v1.0.0 h1:BV7z+2PaK8LTSd/mWgY12HyMAo5CEgkHqbkVq2th github.com/wk8/go-ordered-map v1.0.0/go.mod h1:9ZIbRunKbuvfPKyBP1SIKLcXNlv74YCOZ3t3VTS6gRk= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= @@ -1551,15 +1571,15 @@ gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2 go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= +go.etcd.io/etcd/api/v3 v3.6.6 h1:mcaMp3+7JawWv69p6QShYWS8cIWUOl32bFLb6qf8pOQ= +go.etcd.io/etcd/api/v3 v3.6.6/go.mod h1:f/om26iXl2wSkcTA1zGQv8reJRSLVdoEBsi4JdfMrx4= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= +go.etcd.io/etcd/client/pkg/v3 v3.6.6 h1:uoqgzSOv2H9KlIF5O1Lsd8sW+eMLuV6wzE3q5GJGQNs= +go.etcd.io/etcd/client/pkg/v3 v3.6.6/go.mod h1:YngfUVmvsvOJ2rRgStIyHsKtOt9SZI2aBJrZiWJhCbI= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/client/v3 v3.6.6 h1:G5z1wMf5B9SNexoxOHUGBaULurOZPIgGPsW6CN492ec= +go.etcd.io/etcd/client/v3 v3.6.6/go.mod h1:36Qv6baQ07znPR3+n7t+Rk5VHEzVYPvFfGmfF4wBHV8= go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA= go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE= go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU= @@ -1591,19 +1611,19 @@ go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 h1:2pn7OzMewmYRiNtv1doZnLo3gONcnMHlFnmOR8Vgt+8= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0/go.mod h1:rjbQTDEPQymPE0YnRQp9/NuPwwtL0sesz/fnqRW/v84= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 h1:nXGeLvT1QtCAhkASkP/ksjkTKZALIaQBIW+JSIw1KIc= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0/go.mod h1:oMvOXk78ZR3KEuPMBgp/ThAMDy9ku/eyUVztr+3G6Wo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 h1:oPW/SRFyHgIgxrvNhSBzqvZER2N5kRlci3/rGTOuyWo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0/go.mod h1:B9Oka5QVD0bnmZNO6gBbBta6nohD/1Z+f9waH2oXyBs= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= @@ -1614,12 +1634,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= @@ -1631,20 +1651,20 @@ go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0/go.mod h1:mgIOzS7i go.opentelemetry.io/otel/log v0.12.2 h1:yob9JVHn2ZY24byZeaXpTVoPS6l+UrrxmxmPKohXTwc= go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCfuEbVZi/98E= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= @@ -1686,8 +1706,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1701,8 +1721,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1729,8 +1749,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1785,8 +1805,8 @@ golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1809,8 +1829,8 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1823,8 +1843,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1914,14 +1934,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1931,8 +1951,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1999,8 +2019,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2153,10 +2173,10 @@ google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 h1:Nt6z9UHqSlIdIGJdz6KhTIs2VRx/iOsA5iE8bmQNcxs= google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79/go.mod h1:kTmlBHMPqR5uCZPBvwa2B18mvubkjyY3CRLI0c6fj0s= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -2207,8 +2227,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -2219,8 +2239,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -2257,28 +2277,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= -k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ= -k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/component-base v0.34.3 h1:zsEgw6ELqK0XncCQomgO9DpUIzlrYuZYA0Cgo+JWpVk= +k8s.io/component-base v0.34.3/go.mod h1:5iIlD8wPfWE/xSHTRfbjuvUul2WZbI2nOUK65XL0E/c= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.34.2 h1:91rj4MDZLyIT9KxG8J5/CcMH666Z88CF/xJQeuPfJc8= -k8s.io/kms v0.34.2/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= -k8s.io/kube-aggregator v0.34.2 h1:Nn0Vksj67WHBL2x7bJ6vuxL44RbMTK6uRtXX+3vMVJk= -k8s.io/kube-aggregator v0.34.2/go.mod h1:/tp4cc/1p2AvICsS4mjjSJakdrbhcGbRmj0mdHTdR2Q= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kms v0.34.3 h1:QzBOD0sk1bGQVMcZQAHGjtbP1iKZJUyhC6D0I+BTxIE= +k8s.io/kms v0.34.3/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= +k8s.io/kube-aggregator v0.34.3 h1:rKsZWTD2As4dKuv+zzdJU0uo5H7bFlAEoSucai4mW6M= +k8s.io/kube-aggregator v0.34.3/go.mod h1:d4D8PV2FK4Qlq6u442FSum1tHPhK9tKdKBfH/A3R0I0= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4= modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A= @@ -2305,14 +2325,16 @@ modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/iam/kinds/manifest.cue b/apps/iam/kinds/manifest.cue index bc9c3d47ad7..91f746c6a32 100644 --- a/apps/iam/kinds/manifest.cue +++ b/apps/iam/kinds/manifest.cue @@ -22,4 +22,71 @@ v0alpha1: { serviceaccountv0alpha1, externalGroupMappingv0alpha1 ] + + routes: { + namespaced: { + "/searchUsers": { + "GET": { + request: { + query: { + query?: string + limit?: int64 | 10 + offset?: int64 | 0 + page?: int64 | 1 + } + } + response: { + offset: int64 + totalHits: int64 + hits: [...#UserHit] + queryCost: float64 + maxScore: float64 + } + responseMetadata: { + typeMeta: false + objectMeta: false + } + } + } + "/searchTeams": { + "GET": { + request: { + query: { + query?: string + limit?: int64 | 50 + offset?: int64 | 0 + page?: int64 | 1 + } + } + response: { + #TeamHit: { + name: string + title: string + email: string + provisioned: bool + externalUID: string + } + offset: int64 + totalHits: int64 + hits: [...#TeamHit] + queryCost: float64 + maxScore: float64 + } + responseMetadata: objectMeta: false + } + } + } + } +} + +#UserHit: { + name: string + title: string + login: string + email: string + role: string + lastSeenAt: int64 + lastSeenAtAge: string + provisioned: bool + score: float64 } diff --git a/apps/iam/kinds/user.cue b/apps/iam/kinds/user.cue index a67c0949e1f..fc5bb8fb153 100644 --- a/apps/iam/kinds/user.cue +++ b/apps/iam/kinds/user.cue @@ -29,6 +29,9 @@ userv0alpha1: userKind & { // } schema: { spec: v0alpha1.UserSpec + status: { + lastSeenAt: int64 | 0 + } } // TODO: Uncomment when the custom routes implementation is done // routes: { diff --git a/apps/iam/pkg/apis/iam/v0alpha1/corerole_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/corerole_object_gen.go index 625cced10b9..9a99aadddee 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/corerole_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/corerole_object_gen.go @@ -23,6 +23,12 @@ type CoreRole struct { Spec CoreRoleSpec `json:"spec" yaml:"spec"` } +func NewCoreRole() *CoreRole { + return &CoreRole{ + Spec: *NewCoreRoleSpec(), + } +} + func (o *CoreRole) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/corerole_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/corerole_schema_gen.go index 637f78355f8..82c0a8102e0 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/corerole_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/corerole_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaCoreRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &CoreRole{}, &CoreRoleList{}, resource.WithKind("CoreRole"), + schemaCoreRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewCoreRole(), &CoreRoleList{}, resource.WithKind("CoreRole"), resource.WithPlural("coreroles"), resource.WithScope(resource.NamespacedScope)) kindCoreRole = resource.Kind{ Schema: schemaCoreRole, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/extensions.go b/apps/iam/pkg/apis/iam/v0alpha1/extensions.go deleted file mode 100644 index c0c5a11f7e3..00000000000 --- a/apps/iam/pkg/apis/iam/v0alpha1/extensions.go +++ /dev/null @@ -1,43 +0,0 @@ -package v0alpha1 - -import ( - "fmt" - - "github.com/grafana/grafana/pkg/apimachinery/utils" -) - -func (u User) AuthID() string { - meta, err := utils.MetaAccessor(&u) - if err != nil { - return "" - } - // TODO: Workaround until we move all definitions - // After having all resource definitions here in the app, we can remove this - // and we need to change the List authorization to use the MetaAccessor and the GetDeprecatedInternalID method - //nolint:staticcheck - return fmt.Sprintf("%d", meta.GetDeprecatedInternalID()) -} - -func (s ServiceAccount) AuthID() string { - meta, err := utils.MetaAccessor(&s) - if err != nil { - return "" - } - // TODO: Workaround until we move all definitions - // After having all resource definitions here in the app, we can remove this - // and we need to change the List authorization to use the MetaAccessor and the GetDeprecatedInternalID method - //nolint:staticcheck - return fmt.Sprintf("%d", meta.GetDeprecatedInternalID()) -} - -func (t Team) AuthID() string { - meta, err := utils.MetaAccessor(&t) - if err != nil { - return "" - } - // TODO: Workaround until we move all definitions - // After having all resource definitions here in the app, we can remove this - // and we need to change the List authorization to use the MetaAccessor and the GetDeprecatedInternalID method - //nolint:staticcheck - return fmt.Sprintf("%d", meta.GetDeprecatedInternalID()) -} diff --git a/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_object_gen.go index db20616c355..bbc7c2f65c4 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_object_gen.go @@ -23,6 +23,12 @@ type ExternalGroupMapping struct { Spec ExternalGroupMappingSpec `json:"spec" yaml:"spec"` } +func NewExternalGroupMapping() *ExternalGroupMapping { + return &ExternalGroupMapping{ + Spec: *NewExternalGroupMappingSpec(), + } +} + func (o *ExternalGroupMapping) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_schema_gen.go index 91090a9b460..943c41d8e3e 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/externalgroupmapping_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaExternalGroupMapping = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &ExternalGroupMapping{}, &ExternalGroupMappingList{}, resource.WithKind("ExternalGroupMapping"), + schemaExternalGroupMapping = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewExternalGroupMapping(), &ExternalGroupMappingList{}, resource.WithKind("ExternalGroupMapping"), resource.WithPlural("externalgroupmappings"), resource.WithScope(resource.NamespacedScope)) kindExternalGroupMapping = resource.Kind{ Schema: schemaExternalGroupMapping, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_request_params_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_request_params_object_gen.go new file mode 100644 index 00000000000..76ba539c798 --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_request_params_object_gen.go @@ -0,0 +1,33 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type GetSearchTeamsRequestParamsObject struct { + metav1.TypeMeta `json:",inline"` + GetSearchTeamsRequestParams `json:",inline"` +} + +func NewGetSearchTeamsRequestParamsObject() *GetSearchTeamsRequestParamsObject { + return &GetSearchTeamsRequestParamsObject{} +} + +func (o *GetSearchTeamsRequestParamsObject) DeepCopyObject() runtime.Object { + dst := NewGetSearchTeamsRequestParamsObject() + o.DeepCopyInto(dst) + return dst +} + +func (o *GetSearchTeamsRequestParamsObject) DeepCopyInto(dst *GetSearchTeamsRequestParamsObject) { + dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion + dst.TypeMeta.Kind = o.TypeMeta.Kind + dstGetSearchTeamsRequestParams := GetSearchTeamsRequestParams{} + _ = resource.CopyObjectInto(&dstGetSearchTeamsRequestParams, &o.GetSearchTeamsRequestParams) +} + +var _ runtime.Object = NewGetSearchTeamsRequestParamsObject() diff --git a/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_request_params_types_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_request_params_types_gen.go new file mode 100644 index 00000000000..d06550cb417 --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_request_params_types_gen.go @@ -0,0 +1,15 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +type GetSearchTeamsRequestParams struct { + Query *string `json:"query,omitempty"` + Limit int64 `json:"limit,omitempty"` + Offset int64 `json:"offset,omitempty"` + Page int64 `json:"page,omitempty"` +} + +// NewGetSearchTeamsRequestParams creates a new GetSearchTeamsRequestParams object. +func NewGetSearchTeamsRequestParams() *GetSearchTeamsRequestParams { + return &GetSearchTeamsRequestParams{} +} diff --git a/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_response_body_types_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_response_body_types_gen.go new file mode 100644 index 00000000000..9fabe93260d --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_response_body_types_gen.go @@ -0,0 +1,33 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// +k8s:openapi-gen=true +type VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit struct { + Name string `json:"name"` + Title string `json:"title"` + Email string `json:"email"` + Provisioned bool `json:"provisioned"` + ExternalUID string `json:"externalUID"` +} + +// NewVersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit creates a new VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit object. +func NewVersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit() *VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit { + return &VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit{} +} + +// +k8s:openapi-gen=true +type GetSearchTeamsBody struct { + Offset int64 `json:"offset"` + TotalHits int64 `json:"totalHits"` + Hits []VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit `json:"hits"` + QueryCost float64 `json:"queryCost"` + MaxScore float64 `json:"maxScore"` +} + +// NewGetSearchTeamsBody creates a new GetSearchTeamsBody object. +func NewGetSearchTeamsBody() *GetSearchTeamsBody { + return &GetSearchTeamsBody{ + Hits: []VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit{}, + } +} diff --git a/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_response_object_types_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_response_object_types_gen.go new file mode 100644 index 00000000000..685bd7d85be --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/getsearchteams_response_object_types_gen.go @@ -0,0 +1,37 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// +k8s:openapi-gen=true +type GetSearchTeams struct { + metav1.TypeMeta `json:",inline"` + GetSearchTeamsBody `json:",inline"` +} + +func NewGetSearchTeams() *GetSearchTeams { + return &GetSearchTeams{} +} + +func (t *GetSearchTeamsBody) DeepCopyInto(dst *GetSearchTeamsBody) { + _ = resource.CopyObjectInto(dst, t) +} + +func (o *GetSearchTeams) DeepCopyObject() runtime.Object { + dst := NewGetSearchTeams() + o.DeepCopyInto(dst) + return dst +} + +func (o *GetSearchTeams) DeepCopyInto(dst *GetSearchTeams) { + dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion + dst.TypeMeta.Kind = o.TypeMeta.Kind + o.GetSearchTeamsBody.DeepCopyInto(&dst.GetSearchTeamsBody) +} + +var _ runtime.Object = NewGetSearchTeams() diff --git a/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_request_params_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_request_params_object_gen.go new file mode 100644 index 00000000000..3a6c04a1fa0 --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_request_params_object_gen.go @@ -0,0 +1,33 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type GetSearchUsersRequestParamsObject struct { + metav1.TypeMeta `json:",inline"` + GetSearchUsersRequestParams `json:",inline"` +} + +func NewGetSearchUsersRequestParamsObject() *GetSearchUsersRequestParamsObject { + return &GetSearchUsersRequestParamsObject{} +} + +func (o *GetSearchUsersRequestParamsObject) DeepCopyObject() runtime.Object { + dst := NewGetSearchUsersRequestParamsObject() + o.DeepCopyInto(dst) + return dst +} + +func (o *GetSearchUsersRequestParamsObject) DeepCopyInto(dst *GetSearchUsersRequestParamsObject) { + dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion + dst.TypeMeta.Kind = o.TypeMeta.Kind + dstGetSearchUsersRequestParams := GetSearchUsersRequestParams{} + _ = resource.CopyObjectInto(&dstGetSearchUsersRequestParams, &o.GetSearchUsersRequestParams) +} + +var _ runtime.Object = NewGetSearchUsersRequestParamsObject() diff --git a/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_request_params_types_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_request_params_types_gen.go new file mode 100644 index 00000000000..22b73ea80d8 --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_request_params_types_gen.go @@ -0,0 +1,15 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +type GetSearchUsersRequestParams struct { + Query *string `json:"query,omitempty"` + Limit int64 `json:"limit,omitempty"` + Offset int64 `json:"offset,omitempty"` + Page int64 `json:"page,omitempty"` +} + +// NewGetSearchUsersRequestParams creates a new GetSearchUsersRequestParams object. +func NewGetSearchUsersRequestParams() *GetSearchUsersRequestParams { + return &GetSearchUsersRequestParams{} +} diff --git a/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_response_types_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_response_types_gen.go new file mode 100644 index 00000000000..d56cbfa3a3c --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/getsearchusers_response_types_gen.go @@ -0,0 +1,37 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// +k8s:openapi-gen=true +type UserHit struct { + Name string `json:"name"` + Title string `json:"title"` + Login string `json:"login"` + Email string `json:"email"` + Role string `json:"role"` + LastSeenAt int64 `json:"lastSeenAt"` + LastSeenAtAge string `json:"lastSeenAtAge"` + Provisioned bool `json:"provisioned"` + Score float64 `json:"score"` +} + +// NewUserHit creates a new UserHit object. +func NewUserHit() *UserHit { + return &UserHit{} +} + +// +k8s:openapi-gen=true +type GetSearchUsers struct { + Offset int64 `json:"offset"` + TotalHits int64 `json:"totalHits"` + Hits []UserHit `json:"hits"` + QueryCost float64 `json:"queryCost"` + MaxScore float64 `json:"maxScore"` +} + +// NewGetSearchUsers creates a new GetSearchUsers object. +func NewGetSearchUsers() *GetSearchUsers { + return &GetSearchUsers{ + Hits: []UserHit{}, + } +} diff --git a/apps/iam/pkg/apis/iam/v0alpha1/globalrole_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/globalrole_object_gen.go index 27165fe70bd..66ad21c83cf 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/globalrole_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/globalrole_object_gen.go @@ -23,6 +23,12 @@ type GlobalRole struct { Spec GlobalRoleSpec `json:"spec" yaml:"spec"` } +func NewGlobalRole() *GlobalRole { + return &GlobalRole{ + Spec: *NewGlobalRoleSpec(), + } +} + func (o *GlobalRole) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/globalrole_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/globalrole_schema_gen.go index ce3322f97c0..be220cb0e95 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/globalrole_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/globalrole_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaGlobalRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &GlobalRole{}, &GlobalRoleList{}, resource.WithKind("GlobalRole"), + schemaGlobalRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewGlobalRole(), &GlobalRoleList{}, resource.WithKind("GlobalRole"), resource.WithPlural("globalroles"), resource.WithScope(resource.NamespacedScope)) kindGlobalRole = resource.Kind{ Schema: schemaGlobalRole, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_object_gen.go index 3bd4609d25d..bb8b0644f62 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_object_gen.go @@ -23,6 +23,12 @@ type GlobalRoleBinding struct { Spec GlobalRoleBindingSpec `json:"spec" yaml:"spec"` } +func NewGlobalRoleBinding() *GlobalRoleBinding { + return &GlobalRoleBinding{ + Spec: *NewGlobalRoleBindingSpec(), + } +} + func (o *GlobalRoleBinding) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_schema_gen.go index 9b4e65aa5e6..2e39da946f9 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/globalrolebinding_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaGlobalRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &GlobalRoleBinding{}, &GlobalRoleBindingList{}, resource.WithKind("GlobalRoleBinding"), + schemaGlobalRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewGlobalRoleBinding(), &GlobalRoleBindingList{}, resource.WithKind("GlobalRoleBinding"), resource.WithPlural("globalrolebindings"), resource.WithScope(resource.NamespacedScope)) kindGlobalRoleBinding = resource.Kind{ Schema: schemaGlobalRoleBinding, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/register.go b/apps/iam/pkg/apis/iam/v0alpha1/register.go index be70a0e1714..05dbc30e684 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/register.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/register.go @@ -317,6 +317,7 @@ func AddAuthNKnownTypes(scheme *runtime.Scheme) error { &ServiceAccountList{}, &Team{}, &TeamList{}, + &GetSearchTeams{}, &TeamBinding{}, &TeamBindingList{}, &ExternalGroupMapping{}, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_object_gen.go index 996beb7e002..8cc4c28c209 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_object_gen.go @@ -23,6 +23,12 @@ type ResourcePermission struct { Spec ResourcePermissionSpec `json:"spec" yaml:"spec"` } +func NewResourcePermission() *ResourcePermission { + return &ResourcePermission{ + Spec: *NewResourcePermissionSpec(), + } +} + func (o *ResourcePermission) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_schema_gen.go index 257255a58fe..aa709f0d42a 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/resourcepermission_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaResourcePermission = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &ResourcePermission{}, &ResourcePermissionList{}, resource.WithKind("ResourcePermission"), + schemaResourcePermission = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewResourcePermission(), &ResourcePermissionList{}, resource.WithKind("ResourcePermission"), resource.WithPlural("resourcepermissions"), resource.WithScope(resource.NamespacedScope)) kindResourcePermission = resource.Kind{ Schema: schemaResourcePermission, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/role_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/role_object_gen.go index 20bb587157e..0673c1a17c5 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/role_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/role_object_gen.go @@ -23,6 +23,12 @@ type Role struct { Spec RoleSpec `json:"spec" yaml:"spec"` } +func NewRole() *Role { + return &Role{ + Spec: *NewRoleSpec(), + } +} + func (o *Role) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/role_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/role_schema_gen.go index 74cc8730026..3aacfa2e060 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/role_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/role_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &Role{}, &RoleList{}, resource.WithKind("Role"), + schemaRole = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewRole(), &RoleList{}, resource.WithKind("Role"), resource.WithPlural("roles"), resource.WithScope(resource.NamespacedScope)) kindRole = resource.Kind{ Schema: schemaRole, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_object_gen.go index dfd7741e05a..996fdc3df65 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_object_gen.go @@ -23,6 +23,12 @@ type RoleBinding struct { Spec RoleBindingSpec `json:"spec" yaml:"spec"` } +func NewRoleBinding() *RoleBinding { + return &RoleBinding{ + Spec: *NewRoleBindingSpec(), + } +} + func (o *RoleBinding) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_schema_gen.go index abb2b3eddf9..0cf1d4dee8b 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/rolebinding_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &RoleBinding{}, &RoleBindingList{}, resource.WithKind("RoleBinding"), + schemaRoleBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewRoleBinding(), &RoleBindingList{}, resource.WithKind("RoleBinding"), resource.WithPlural("rolebindings"), resource.WithScope(resource.NamespacedScope)) kindRoleBinding = resource.Kind{ Schema: schemaRoleBinding, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_object_gen.go index fe3cd7f3609..e2cfc9f33a7 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_object_gen.go @@ -23,6 +23,12 @@ type ServiceAccount struct { Spec ServiceAccountSpec `json:"spec" yaml:"spec"` } +func NewServiceAccount() *ServiceAccount { + return &ServiceAccount{ + Spec: *NewServiceAccountSpec(), + } +} + func (o *ServiceAccount) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_schema_gen.go index ea48c864739..71b171e0756 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/serviceaccount_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaServiceAccount = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &ServiceAccount{}, &ServiceAccountList{}, resource.WithKind("ServiceAccount"), + schemaServiceAccount = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewServiceAccount(), &ServiceAccountList{}, resource.WithKind("ServiceAccount"), resource.WithPlural("serviceaccounts"), resource.WithScope(resource.NamespacedScope)) kindServiceAccount = resource.Kind{ Schema: schemaServiceAccount, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/team_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/team_object_gen.go index 4030bebb9d1..85b57abf9d5 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/team_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/team_object_gen.go @@ -23,6 +23,12 @@ type Team struct { Spec TeamSpec `json:"spec" yaml:"spec"` } +func NewTeam() *Team { + return &Team{ + Spec: *NewTeamSpec(), + } +} + func (o *Team) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/team_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/team_schema_gen.go index 7a4875cf2d5..299d846d10e 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/team_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/team_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaTeam = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &Team{}, &TeamList{}, resource.WithKind("Team"), + schemaTeam = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewTeam(), &TeamList{}, resource.WithKind("Team"), resource.WithPlural("teams"), resource.WithScope(resource.NamespacedScope)) kindTeam = resource.Kind{ Schema: schemaTeam, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/team_search.go b/apps/iam/pkg/apis/iam/v0alpha1/team_search.go new file mode 100644 index 00000000000..545552a4795 --- /dev/null +++ b/apps/iam/pkg/apis/iam/v0alpha1/team_search.go @@ -0,0 +1,35 @@ +package v0alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen=true +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type TeamSearchResults struct { + metav1.TypeMeta `json:",inline"` + + // Where the query started from + Offset int64 `json:"offset,omitempty"` + + // The number of matching results + TotalHits int64 `json:"totalHits"` + + // The team body + Hits []TeamHit `json:"hits"` + + // Cost of running the query + QueryCost float64 `json:"queryCost,omitempty"` + + // Max score + MaxScore float64 `json:"maxScore,omitempty"` +} + +// +k8s:deepcopy-gen=true +type TeamHit struct { + Name string `json:"name"` + Title string `json:"title"` + Email string `json:"email,omitempty"` + Provisioned bool `json:"provisioned,omitempty"` + ExternalUID string `json:"externalUID,omitempty"` +} diff --git a/apps/iam/pkg/apis/iam/v0alpha1/teambinding_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/teambinding_object_gen.go index a958c55f5e7..0d388192448 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/teambinding_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/teambinding_object_gen.go @@ -23,6 +23,12 @@ type TeamBinding struct { Spec TeamBindingSpec `json:"spec" yaml:"spec"` } +func NewTeamBinding() *TeamBinding { + return &TeamBinding{ + Spec: *NewTeamBindingSpec(), + } +} + func (o *TeamBinding) GetSpec() any { return o.Spec } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/teambinding_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/teambinding_schema_gen.go index e3c2c11a8b5..d089b966e9b 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/teambinding_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/teambinding_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaTeamBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &TeamBinding{}, &TeamBindingList{}, resource.WithKind("TeamBinding"), + schemaTeamBinding = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewTeamBinding(), &TeamBindingList{}, resource.WithKind("TeamBinding"), resource.WithPlural("teambindings"), resource.WithScope(resource.NamespacedScope)) kindTeamBinding = resource.Kind{ Schema: schemaTeamBinding, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/user_client_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/user_client_gen.go index 665df84327e..bd7af9b3361 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/user_client_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/user_client_gen.go @@ -4,6 +4,7 @@ import ( "context" "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type UserClient struct { @@ -75,6 +76,24 @@ func (c *UserClient) Patch(ctx context.Context, identifier resource.Identifier, return c.client.Patch(ctx, identifier, req, opts) } +func (c *UserClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus UserStatus, opts resource.UpdateOptions) (*User, error) { + return c.client.Update(ctx, &User{ + TypeMeta: metav1.TypeMeta{ + Kind: UserKind().Kind(), + APIVersion: GroupVersion.Identifier(), + }, + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: opts.ResourceVersion, + Namespace: identifier.Namespace, + Name: identifier.Name, + }, + Status: newStatus, + }, resource.UpdateOptions{ + Subresource: "status", + ResourceVersion: opts.ResourceVersion, + }) +} + func (c *UserClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error { return c.client.Delete(ctx, identifier, opts) } diff --git a/apps/iam/pkg/apis/iam/v0alpha1/user_object_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/user_object_gen.go index 373112a1d87..f4bc19dccbb 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/user_object_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/user_object_gen.go @@ -21,6 +21,15 @@ type User struct { // Spec is the spec of the User Spec UserSpec `json:"spec" yaml:"spec"` + + Status UserStatus `json:"status" yaml:"status"` +} + +func NewUser() *User { + return &User{ + Spec: *NewUserSpec(), + Status: *NewUserStatus(), + } } func (o *User) GetSpec() any { @@ -37,11 +46,15 @@ func (o *User) SetSpec(spec any) error { } func (o *User) GetSubresources() map[string]any { - return map[string]any{} + return map[string]any{ + "status": o.Status, + } } func (o *User) GetSubresource(name string) (any, bool) { switch name { + case "status": + return o.Status, true default: return nil, false } @@ -49,6 +62,13 @@ func (o *User) GetSubresource(name string) (any, bool) { func (o *User) SetSubresource(name string, value any) error { switch name { + case "status": + cast, ok := value.(UserStatus) + if !ok { + return fmt.Errorf("cannot set status type %#v, not of type UserStatus", value) + } + o.Status = cast + return nil default: return fmt.Errorf("subresource '%s' does not exist", name) } @@ -220,6 +240,7 @@ func (o *User) DeepCopyInto(dst *User) { dst.TypeMeta.Kind = o.TypeMeta.Kind o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta) o.Spec.DeepCopyInto(&dst.Spec) + o.Status.DeepCopyInto(&dst.Status) } // Interface compliance compile-time check @@ -291,3 +312,15 @@ func (s *UserSpec) DeepCopy() *UserSpec { func (s *UserSpec) DeepCopyInto(dst *UserSpec) { resource.CopyObjectInto(dst, s) } + +// DeepCopy creates a full deep copy of UserStatus +func (s *UserStatus) DeepCopy() *UserStatus { + cpy := &UserStatus{} + s.DeepCopyInto(cpy) + return cpy +} + +// DeepCopyInto deep copies UserStatus into another UserStatus object +func (s *UserStatus) DeepCopyInto(dst *UserStatus) { + resource.CopyObjectInto(dst, s) +} diff --git a/apps/iam/pkg/apis/iam/v0alpha1/user_schema_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/user_schema_gen.go index a44d9dfcf2d..ba48b19c015 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/user_schema_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/user_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaUser = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", &User{}, &UserList{}, resource.WithKind("User"), + schemaUser = resource.NewSimpleSchema("iam.grafana.app", "v0alpha1", NewUser(), &UserList{}, resource.WithKind("User"), resource.WithPlural("users"), resource.WithScope(resource.NamespacedScope)) kindUser = resource.Kind{ Schema: schemaUser, diff --git a/apps/iam/pkg/apis/iam/v0alpha1/user_status_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/user_status_gen.go index 34a138f59ce..dd0f3e46767 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/user_status_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/user_status_gen.go @@ -2,43 +2,12 @@ package v0alpha1 -// +k8s:openapi-gen=true -type UserstatusOperatorState struct { - // lastEvaluation is the ResourceVersion last evaluated - LastEvaluation string `json:"lastEvaluation"` - // state describes the state of the lastEvaluation. - // It is limited to three possible states for machine evaluation. - State UserStatusOperatorStateState `json:"state"` - // descriptiveState is an optional more descriptive state field which has no requirements on format - DescriptiveState *string `json:"descriptiveState,omitempty"` - // details contains any extra information that is operator-specific - Details map[string]interface{} `json:"details,omitempty"` -} - -// NewUserstatusOperatorState creates a new UserstatusOperatorState object. -func NewUserstatusOperatorState() *UserstatusOperatorState { - return &UserstatusOperatorState{} -} - // +k8s:openapi-gen=true type UserStatus struct { - // operatorStates is a map of operator ID to operator state evaluations. - // Any operator which consumes this kind SHOULD add its state evaluation information to this field. - OperatorStates map[string]UserstatusOperatorState `json:"operatorStates,omitempty"` - // additionalFields is reserved for future use - AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` + LastSeenAt int64 `json:"lastSeenAt"` } // NewUserStatus creates a new UserStatus object. func NewUserStatus() *UserStatus { return &UserStatus{} } - -// +k8s:openapi-gen=true -type UserStatusOperatorStateState string - -const ( - UserStatusOperatorStateStateSuccess UserStatusOperatorStateState = "success" - UserStatusOperatorStateStateInProgress UserStatusOperatorStateState = "in_progress" - UserStatusOperatorStateStateFailed UserStatusOperatorStateState = "failed" -) diff --git a/apps/iam/pkg/apis/iam/v0alpha1/zz_openapi_gen.go b/apps/iam/pkg/apis/iam/v0alpha1/zz_openapi_gen.go index e3b024799d7..87128d27699 100644 --- a/apps/iam/pkg/apis/iam/v0alpha1/zz_openapi_gen.go +++ b/apps/iam/pkg/apis/iam/v0alpha1/zz_openapi_gen.go @@ -1,8 +1,3 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// Code generated by grafana-app-sdk. DO NOT EDIT. - package v0alpha1 import ( @@ -24,6 +19,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.ExternalGroupMappingTeamRef": schema_pkg_apis_iam_v0alpha1_ExternalGroupMappingTeamRef(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GetGroups": schema_pkg_apis_iam_v0alpha1_GetGroups(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GetGroupsBody": schema_pkg_apis_iam_v0alpha1_GetGroupsBody(ref), + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GetSearchTeams": schema_pkg_apis_iam_v0alpha1_GetSearchTeams(ref), + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GetSearchTeamsBody": schema_pkg_apis_iam_v0alpha1_GetSearchTeamsBody(ref), + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GetSearchUsers": schema_pkg_apis_iam_v0alpha1_GetSearchUsers(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GlobalRole": schema_pkg_apis_iam_v0alpha1_GlobalRole(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GlobalRoleBinding": schema_pkg_apis_iam_v0alpha1_GlobalRoleBinding(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.GlobalRoleBindingList": schema_pkg_apis_iam_v0alpha1_GlobalRoleBindingList(ref), @@ -75,11 +73,12 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.TeamStatus": schema_pkg_apis_iam_v0alpha1_TeamStatus(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.TeamstatusOperatorState": schema_pkg_apis_iam_v0alpha1_TeamstatusOperatorState(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.User": schema_pkg_apis_iam_v0alpha1_User(ref), + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserHit": schema_pkg_apis_iam_v0alpha1_UserHit(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserList": schema_pkg_apis_iam_v0alpha1_UserList(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserSpec": schema_pkg_apis_iam_v0alpha1_UserSpec(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserStatus": schema_pkg_apis_iam_v0alpha1_UserStatus(ref), - "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserstatusOperatorState": schema_pkg_apis_iam_v0alpha1_UserstatusOperatorState(ref), "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.VersionsV0alpha1Kinds7RoutesGroupsGETResponseExternalGroupMapping": schema_pkg_apis_iam_v0alpha1_VersionsV0alpha1Kinds7RoutesGroupsGETResponseExternalGroupMapping(ref), + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit": schema_pkg_apis_iam_v0alpha1_VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit(ref), } } @@ -564,6 +563,188 @@ func schema_pkg_apis_iam_v0alpha1_GetGroupsBody(ref common.ReferenceCallback) co } } +func schema_pkg_apis_iam_v0alpha1_GetSearchTeams(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "offset": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "totalHits": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "hits": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit"), + }, + }, + }, + }, + }, + "queryCost": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + "maxScore": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + }, + Required: []string{"offset", "totalHits", "hits", "queryCost", "maxScore"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit"}, + } +} + +func schema_pkg_apis_iam_v0alpha1_GetSearchTeamsBody(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "offset": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "totalHits": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "hits": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit"), + }, + }, + }, + }, + }, + "queryCost": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + "maxScore": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + }, + Required: []string{"offset", "totalHits", "hits", "queryCost", "maxScore"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit"}, + } +} + +func schema_pkg_apis_iam_v0alpha1_GetSearchUsers(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "offset": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "totalHits": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "hits": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserHit"), + }, + }, + }, + }, + }, + "queryCost": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + "maxScore": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + }, + Required: []string{"offset", "totalHits", "hits", "queryCost", "maxScore"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserHit"}, + } +} + func schema_pkg_apis_iam_v0alpha1_GlobalRole(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2709,12 +2890,94 @@ func schema_pkg_apis_iam_v0alpha1_User(ref common.ReferenceCallback) common.Open Ref: ref("github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserSpec"), }, }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserStatus"), + }, + }, }, - Required: []string{"metadata", "spec"}, + Required: []string{"metadata", "spec", "status"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserSpec", "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_iam_v0alpha1_UserHit(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "login": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "email": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "role": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "lastSeenAt": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "lastSeenAtAge": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "provisioned": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "score": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + }, + Required: []string{"name", "title", "login", "email", "role", "lastSeenAt", "lastSeenAtAge", "provisioned", "score"}, + }, + }, } } @@ -2841,90 +3104,15 @@ func schema_pkg_apis_iam_v0alpha1_UserStatus(ref common.ReferenceCallback) commo SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ - "operatorStates": { + "lastSeenAt": { SchemaProps: spec.SchemaProps{ - Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserstatusOperatorState"), - }, - }, - }, - }, - }, - "additionalFields": { - SchemaProps: spec.SchemaProps{ - Description: "additionalFields is reserved for future use", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, + Default: 0, + Type: []string{"integer"}, + Format: "int64", }, }, }, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserstatusOperatorState"}, - } -} - -func schema_pkg_apis_iam_v0alpha1_UserstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "lastEvaluation": { - SchemaProps: spec.SchemaProps{ - Description: "lastEvaluation is the ResourceVersion last evaluated", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "state": { - SchemaProps: spec.SchemaProps{ - Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "descriptiveState": { - SchemaProps: spec.SchemaProps{ - Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", - Type: []string{"string"}, - Format: "", - }, - }, - "details": { - SchemaProps: spec.SchemaProps{ - Description: "details contains any extra information that is operator-specific", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - }, - Required: []string{"lastEvaluation", "state"}, + Required: []string{"lastSeenAt"}, }, }, } @@ -2956,3 +3144,51 @@ func schema_pkg_apis_iam_v0alpha1_VersionsV0alpha1Kinds7RoutesGroupsGETResponseE }, } } + +func schema_pkg_apis_iam_v0alpha1_VersionsV0alpha1RoutesNamespacedSearchTeamsGETResponseTeamHit(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "email": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "provisioned": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "externalUID": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "title", "email", "provisioned", "externalUID"}, + }, + }, + } +} diff --git a/apps/iam/pkg/apis/iam_manifest.go b/apps/iam/pkg/apis/iam_manifest.go index 9fe171525b4..664c12226de 100644 --- a/apps/iam/pkg/apis/iam_manifest.go +++ b/apps/iam/pkg/apis/iam_manifest.go @@ -109,6 +109,13 @@ var appManifestData = app.ManifestData{ "items": { SchemaProps: spec.SchemaProps{ Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + + Ref: spec.MustCreateRef("#/components/schemas/getGroupsExternalGroupMapping"), + }}, + }, }, }, "kind": { @@ -157,9 +164,351 @@ var appManifestData = app.ManifestData{ }, }, Routes: app.ManifestVersionRoutes{ - Namespaced: map[string]spec3.PathProps{}, - Cluster: map[string]spec3.PathProps{}, - Schemas: map[string]spec.Schema{}, + Namespaced: map[string]spec3.PathProps{ + "/searchTeams": { + Get: &spec3.Operation{ + OperationProps: spec3.OperationProps{ + + OperationId: "getSearchTeams", + + Parameters: []*spec3.Parameter{ + + { + ParameterProps: spec3.ParameterProps{ + Name: "limit", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{}, + }, + }, + }, + + { + ParameterProps: spec3.ParameterProps{ + Name: "offset", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{}, + }, + }, + }, + + { + ParameterProps: spec3.ParameterProps{ + Name: "page", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{}, + }, + }, + }, + + { + ParameterProps: spec3.ParameterProps{ + Name: "query", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + }, + }, + }, + + Responses: &spec3.Responses{ + ResponsesProps: spec3.ResponsesProps{ + Default: &spec3.Response{ + ResponseProps: spec3.ResponseProps{ + Description: "Default OK response", + Content: map[string]*spec3.MediaType{ + "application/json": { + MediaTypeProps: spec3.MediaTypeProps{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + }, + }, + "hits": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + + Ref: spec.MustCreateRef("#/components/schemas/getSearchTeamsTeamHit"), + }}, + }, + }, + }, + "kind": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + }, + }, + "maxScore": { + SchemaProps: spec.SchemaProps{ + Type: []string{"number"}, + }, + }, + "offset": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + }, + }, + "queryCost": { + SchemaProps: spec.SchemaProps{ + Type: []string{"number"}, + }, + }, + "totalHits": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + }, + }, + }, + Required: []string{ + "offset", + "totalHits", + "hits", + "queryCost", + "maxScore", + "apiVersion", + "kind", + }, + }}, + }}, + }, + }, + }, + }}, + }, + }, + }, + "/searchUsers": { + Get: &spec3.Operation{ + OperationProps: spec3.OperationProps{ + + OperationId: "getSearchUsers", + + Parameters: []*spec3.Parameter{ + + { + ParameterProps: spec3.ParameterProps{ + Name: "limit", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{}, + }, + }, + }, + + { + ParameterProps: spec3.ParameterProps{ + Name: "offset", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{}, + }, + }, + }, + + { + ParameterProps: spec3.ParameterProps{ + Name: "page", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{}, + }, + }, + }, + + { + ParameterProps: spec3.ParameterProps{ + Name: "query", + In: "query", + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + }, + }, + }, + + Responses: &spec3.Responses{ + ResponsesProps: spec3.ResponsesProps{ + Default: &spec3.Response{ + ResponseProps: spec3.ResponseProps{ + Description: "Default OK response", + Content: map[string]*spec3.MediaType{ + "application/json": { + MediaTypeProps: spec3.MediaTypeProps{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "hits": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + + Ref: spec.MustCreateRef("#/components/schemas/getSearchUsersUserHit"), + }}, + }, + }, + }, + "maxScore": { + SchemaProps: spec.SchemaProps{ + Type: []string{"number"}, + }, + }, + "offset": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + }, + }, + "queryCost": { + SchemaProps: spec.SchemaProps{ + Type: []string{"number"}, + }, + }, + "totalHits": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + }, + }, + }, + Required: []string{ + "offset", + "totalHits", + "hits", + "queryCost", + "maxScore", + }, + }}, + }}, + }, + }, + }, + }}, + }, + }, + }, + }, + Cluster: map[string]spec3.PathProps{}, + Schemas: map[string]spec.Schema{ + "getSearchTeamsTeamHit": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "email": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "externalUID": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "provisioned": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + }, + Required: []string{ + "name", + "title", + "email", + "provisioned", + "externalUID", + }, + }, + }, + "getSearchUsersUserHit": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "email": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "lastSeenAt": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + }, + }, + "lastSeenAtAge": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "login": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "provisioned": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + }, + }, + "role": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "score": { + SchemaProps: spec.SchemaProps{ + Type: []string{"number"}, + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + }, + Required: []string{ + "name", + "title", + "login", + "email", + "role", + "lastSeenAt", + "lastSeenAtAge", + "provisioned", + "score", + }, + }, + }, + }, }, }, }, @@ -196,6 +545,9 @@ func ManifestGoTypeAssociator(kind, version string) (goType resource.Kind, exist var customRouteToGoResponseType = map[string]any{ "v0alpha1|Team|groups|GET": v0alpha1.GetGroups{}, + + "v0alpha1||/searchTeams|GET": v0alpha1.GetSearchTeams{}, + "v0alpha1||/searchUsers|GET": v0alpha1.GetSearchUsers{}, } // ManifestCustomRouteResponsesAssociator returns the associated response go type for a given kind, version, custom route path, and method, if one exists. diff --git a/apps/iam/pkg/app/app.go b/apps/iam/pkg/app/app.go index 05216220d7e..ff2a0cc7feb 100644 --- a/apps/iam/pkg/app/app.go +++ b/apps/iam/pkg/app/app.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "github.com/prometheus/client_golang/prometheus" + "github.com/grafana/grafana-app-sdk/app" "github.com/grafana/grafana-app-sdk/logging" "github.com/grafana/grafana-app-sdk/operator" @@ -12,7 +14,6 @@ import ( foldersKind "github.com/grafana/grafana/apps/folder/pkg/apis/folder/v1beta1" "github.com/grafana/grafana/apps/iam/pkg/reconcilers" "github.com/grafana/grafana/pkg/services/authz" - "github.com/prometheus/client_golang/prometheus" ) var appManifestData = app.ManifestData{ @@ -78,7 +79,7 @@ func New(cfg app.Config) (app.App, error) { folderReconciler, err := reconcilers.NewFolderReconciler(reconcilers.ReconcilerConfig{ ZanzanaCfg: appSpecificConfig.ZanzanaClientCfg, Metrics: metrics, - }) + }, appSpecificConfig.MetricsRegisterer) if err != nil { return nil, fmt.Errorf("unable to create FolderReconciler: %w", err) } diff --git a/apps/iam/pkg/reconcilers/folder_reconciler.go b/apps/iam/pkg/reconcilers/folder_reconciler.go index 066637ee1e6..66a6868722d 100644 --- a/apps/iam/pkg/reconcilers/folder_reconciler.go +++ b/apps/iam/pkg/reconcilers/folder_reconciler.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/prometheus/client_golang/prometheus" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" @@ -35,9 +36,9 @@ type FolderReconciler struct { metrics *ReconcilerMetrics } -func NewFolderReconciler(cfg ReconcilerConfig) (operator.Reconciler, error) { +func NewFolderReconciler(cfg ReconcilerConfig, reg prometheus.Registerer) (operator.Reconciler, error) { // Create Zanzana client - zanzanaClient, err := authz.NewRemoteZanzanaClient("*", cfg.ZanzanaCfg) + zanzanaClient, err := authz.NewRemoteZanzanaClient(cfg.ZanzanaCfg, reg) if err != nil { return nil, fmt.Errorf("unable to create zanzana client: %w", err) diff --git a/apps/investigations/Makefile b/apps/investigations/Makefile deleted file mode 100644 index aaac06377ca..00000000000 --- a/apps/investigations/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../sdk.mk - -.PHONY: generate -generate: install-app-sdk update-app-sdk - @$(APP_SDK_BIN) generate -g ./pkg/apis --grouping=group --postprocess --defencoding=none --useoldmanifestkinds diff --git a/apps/investigations/example.json b/apps/investigations/example.json deleted file mode 100644 index 0a390fb074f..00000000000 --- a/apps/investigations/example.json +++ /dev/null @@ -1,152 +0,0 @@ -[ - { - "id": "896312ce-65b0-4b50-ade1-e7f04fa22c66", - "title": "Thursday morning investigation", - "hasCustomName": false, - "isFavorite": false, - "collectables": [ - { - "origin": "Explore Logs", - "type": "timeseries", - "queries": [ - { - "refId": "LABEL_BREAKDOWN_VALUES", - "queryType": "range", - "editorMode": "code", - "supportingQueryType": "grafana-lokiexplore-app", - "legendFormat": "{{detected_level}}", - "expr": "sum(count_over_time({service_name=\"web_app_1\"} | detected_level != \"\"[$__auto])) by (detected_level)" - } - ], - "timeRange": { - "to": "2025-02-13T11:31:20.536Z", - "from": "2025-02-13T11:16:20.536Z", - "raw": { - "from": "now-15m", - "to": "now" - } - }, - "datasource": { - "uid": "fe9k7u07b1a0wc" - }, - "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", - "id": "LABEL_BREAKDOWN_VALUES_detected_level", - "title": "detected_level", - "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", - "createdAt": "2025-02-13T11:31:23.637Z" - } - ], - "createdAt": "2025-02-13T11:31:23.636Z", - "updatedAt": "2025-02-13T11:31:23.637Z", - "viewMode": { - "mode": "compact", - "showComments": true, - "showTooltips": false - } - }, - { - "id": "e9cf1958-d0ed-46b7-b597-9052c7648656", - "title": "Thursday morning investigation", - "hasCustomName": false, - "isFavorite": false, - "collectables": [ - { - "origin": "Explore Logs", - "type": "timeseries", - "queries": [ - { - "refId": "LABEL_BREAKDOWN_VALUES", - "queryType": "range", - "editorMode": "code", - "supportingQueryType": "grafana-lokiexplore-app", - "legendFormat": "{{detected_level}}", - "expr": "sum(count_over_time({service_name=\"web_app_1\"} | detected_level != \"\"[$__auto])) by (detected_level)" - } - ], - "timeRange": { - "to": "2025-02-13T11:31:20.536Z", - "from": "2025-02-13T11:16:20.536Z", - "raw": { - "from": "now-15m", - "to": "now" - } - }, - "datasource": { - "uid": "fe9k7u07b1a0wc" - }, - "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", - "id": "LABEL_BREAKDOWN_VALUES_detected_level", - "title": "detected_level", - "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", - "createdAt": "2025-02-13T11:31:23.638Z" - }, - { - "origin": "Explore Logs", - "type": "timeseries", - "queries": [ - { - "refId": "LABEL_BREAKDOWN_VALUES", - "queryType": "range", - "editorMode": "code", - "supportingQueryType": "grafana-lokiexplore-app", - "legendFormat": "{{service_name}}", - "expr": "sum(count_over_time({service_name=\"web_app_1\",service_name != \"\"} [$__auto])) by (service_name)" - } - ], - "timeRange": { - "to": "2025-02-13T11:31:20.536Z", - "from": "2025-02-13T11:16:20.536Z", - "raw": { - "from": "now-15m", - "to": "now" - } - }, - "datasource": { - "uid": "fe9k7u07b1a0wc" - }, - "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", - "id": "LABEL_BREAKDOWN_VALUES_service_name", - "title": "service_name", - "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", - "createdAt": "2025-02-13T11:31:41.507Z" - }, - { - "origin": "Explore Logs", - "type": "timeseries", - "queries": [ - { - "refId": "LABEL_BREAKDOWN_VALUES", - "queryType": "range", - "editorMode": "code", - "supportingQueryType": "grafana-lokiexplore-app", - "legendFormat": "{{service}}", - "expr": "sum(count_over_time({service_name=\"web_app_1\",service != \"\"} [$__auto])) by (service)" - } - ], - "timeRange": { - "to": "2025-02-13T11:31:20.536Z", - "from": "2025-02-13T11:16:20.536Z", - "raw": { - "from": "now-15m", - "to": "now" - } - }, - "datasource": { - "uid": "fe9k7u07b1a0wc" - }, - "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", - "id": "LABEL_BREAKDOWN_VALUES_service", - "title": "service", - "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", - "createdAt": "2025-02-13T11:31:43.698Z" - } - ], - "createdAt": "2025-02-13T11:31:23.637Z", - "updatedAt": "2025-02-13T11:31:43.698Z", - "viewMode": { - "mode": "compact", - "showComments": true, - "showTooltips": false - } - } -] diff --git a/apps/investigations/kinds/collectable.cue b/apps/investigations/kinds/collectable.cue deleted file mode 100644 index f9fc754a67c..00000000000 --- a/apps/investigations/kinds/collectable.cue +++ /dev/null @@ -1,43 +0,0 @@ -package investigations - -// Collectable represents an item collected during investigation -#Collectable: { - id: string - createdAt: string - - title: string - origin: string - type: string - queries: [...string] // +listType=atomic - timeRange: #TimeRange - datasource: #DatasourceRef - url: string - logoPath?: string - - note: string - noteUpdatedAt: string - - fieldConfig: string -} - -#CollectableSummary: { - id: string - title: string - logoPath: string - origin: string -} - -// TimeRange represents a time range with both absolute and relative values -#TimeRange: { - from: string - to: string - raw: { - from: string - to: string - } -} - -// DatasourceRef is a reference to a datasource -#DatasourceRef: { - uid: string -} diff --git a/apps/investigations/kinds/cue.mod/module.cue b/apps/investigations/kinds/cue.mod/module.cue deleted file mode 100644 index c592b1ce788..00000000000 --- a/apps/investigations/kinds/cue.mod/module.cue +++ /dev/null @@ -1,4 +0,0 @@ -module: "github.com/grafana/grafana/apps/investigations" -language: { - version: "v0.11.0" -} \ No newline at end of file diff --git a/apps/investigations/kinds/investigation.cue b/apps/investigations/kinds/investigation.cue deleted file mode 100644 index f1e9a69027f..00000000000 --- a/apps/investigations/kinds/investigation.cue +++ /dev/null @@ -1,64 +0,0 @@ -package investigations - -// This is our Investigation definition, which contains metadata about the kind, and the kind's schema -investigation: { - kind: "Investigation" - group: "investigations.grafana.app" - apiResource: { - groupOverride: "investigations.grafana.app" - } - pluralName: "Investigations" - current: "v0alpha1" - versions: { - "v0alpha1": { - codegen: { - frontend: true - backend: true - options: { - generateObjectMeta: true - generateClient: true - k8sLike: true - package: "github.com/grafana/grafana/apps/investigations" - } - } - schema: { - // spec is the schema of our resource - spec: { - title: string - createdByProfile: #Person - hasCustomName: bool - isFavorite: bool - overviewNote: string - overviewNoteUpdatedAt: string - collectables: [...#Collectable] // +listType=atomic - viewMode: #ViewMode - } - } - } - } -} - -// Type definition for investigation summaries -#InvestigationSummary: { - title: string - createdByProfile: #Person - hasCustomName: bool - isFavorite: bool - overviewNote: string - overviewNoteUpdatedAt: string - viewMode: #ViewMode - collectableSummaries: [...#CollectableSummary] // +listType=atomic -} - -// Person represents a user profile with basic information -#Person: { - uid: string // Unique identifier for the user - name: string // Display name of the user - gravatarUrl: string // URL to user's Gravatar image -} - -#ViewMode: { - mode: "compact" | "full" - showComments: bool - showTooltips: bool -} diff --git a/apps/investigations/kinds/investigationindex.cue b/apps/investigations/kinds/investigationindex.cue deleted file mode 100644 index 447e156be4f..00000000000 --- a/apps/investigations/kinds/investigationindex.cue +++ /dev/null @@ -1,37 +0,0 @@ -package investigations - -investigationIndex: { - kind: "InvestigationIndex" - group: "investigations.grafana.app" - apiResource: { - groupOverride: "investigations.grafana.app" - } - pluralName: "InvestigationIndexes" - current: "v0alpha1" - versions: { - "v0alpha1": { - codegen: { - frontend: true - backend: true - options: { - generateObjectMeta: true - generateClient: true - k8sLike: true - package: "github.com/grafana/grafana/apps/investigations" - } - } - schema: { - spec: { - // Title of the index, e.g. 'Favorites' or 'My Investigations' - title: string - - // The Person who owns this investigation index - owner: #Person - - // Array of investigation summaries - investigationSummaries: [...#InvestigationSummary] // +listType=atomic - } - } - } - } -} diff --git a/apps/investigations/kinds/manifest.cue b/apps/investigations/kinds/manifest.cue deleted file mode 100644 index d9e93b00061..00000000000 --- a/apps/investigations/kinds/manifest.cue +++ /dev/null @@ -1,10 +0,0 @@ -package investigations - -manifest: { - appName: "investigations" - groupOverride: "investigations.grafana.app" - kinds: [ - investigation, - investigationIndex, - ] -} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_client_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_client_gen.go deleted file mode 100644 index dc73a0301e9..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_client_gen.go +++ /dev/null @@ -1,99 +0,0 @@ -package v0alpha1 - -import ( - "context" - - "github.com/grafana/grafana-app-sdk/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type InvestigationClient struct { - client *resource.TypedClient[*Investigation, *InvestigationList] -} - -func NewInvestigationClient(client resource.Client) *InvestigationClient { - return &InvestigationClient{ - client: resource.NewTypedClient[*Investigation, *InvestigationList](client, InvestigationKind()), - } -} - -func NewInvestigationClientFromGenerator(generator resource.ClientGenerator) (*InvestigationClient, error) { - c, err := generator.ClientFor(InvestigationKind()) - if err != nil { - return nil, err - } - return NewInvestigationClient(c), nil -} - -func (c *InvestigationClient) Get(ctx context.Context, identifier resource.Identifier) (*Investigation, error) { - return c.client.Get(ctx, identifier) -} - -func (c *InvestigationClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*InvestigationList, error) { - return c.client.List(ctx, namespace, opts) -} - -func (c *InvestigationClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*InvestigationList, error) { - resp, err := c.client.List(ctx, namespace, resource.ListOptions{ - ResourceVersion: opts.ResourceVersion, - Limit: opts.Limit, - LabelFilters: opts.LabelFilters, - FieldSelectors: opts.FieldSelectors, - }) - if err != nil { - return nil, err - } - for resp.GetContinue() != "" { - page, err := c.client.List(ctx, namespace, resource.ListOptions{ - Continue: resp.GetContinue(), - ResourceVersion: opts.ResourceVersion, - Limit: opts.Limit, - LabelFilters: opts.LabelFilters, - FieldSelectors: opts.FieldSelectors, - }) - if err != nil { - return nil, err - } - resp.SetContinue(page.GetContinue()) - resp.SetResourceVersion(page.GetResourceVersion()) - resp.SetItems(append(resp.GetItems(), page.GetItems()...)) - } - return resp, nil -} - -func (c *InvestigationClient) Create(ctx context.Context, obj *Investigation, opts resource.CreateOptions) (*Investigation, error) { - // Make sure apiVersion and kind are set - obj.APIVersion = GroupVersion.Identifier() - obj.Kind = InvestigationKind().Kind() - return c.client.Create(ctx, obj, opts) -} - -func (c *InvestigationClient) Update(ctx context.Context, obj *Investigation, opts resource.UpdateOptions) (*Investigation, error) { - return c.client.Update(ctx, obj, opts) -} - -func (c *InvestigationClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*Investigation, error) { - return c.client.Patch(ctx, identifier, req, opts) -} - -func (c *InvestigationClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus InvestigationStatus, opts resource.UpdateOptions) (*Investigation, error) { - return c.client.Update(ctx, &Investigation{ - TypeMeta: metav1.TypeMeta{ - Kind: InvestigationKind().Kind(), - APIVersion: GroupVersion.Identifier(), - }, - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: opts.ResourceVersion, - Namespace: identifier.Namespace, - Name: identifier.Name, - }, - Status: newStatus, - }, resource.UpdateOptions{ - Subresource: "status", - ResourceVersion: opts.ResourceVersion, - }) -} - -func (c *InvestigationClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error { - return c.client.Delete(ctx, identifier, opts) -} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_codec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_codec_gen.go deleted file mode 100644 index 6bde81b50d3..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_codec_gen.go +++ /dev/null @@ -1,28 +0,0 @@ -// -// Code generated by grafana-app-sdk. DO NOT EDIT. -// - -package v0alpha1 - -import ( - "encoding/json" - "io" - - "github.com/grafana/grafana-app-sdk/resource" -) - -// InvestigationJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding -type InvestigationJSONCodec struct{} - -// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` -func (*InvestigationJSONCodec) Read(reader io.Reader, into resource.Object) error { - return json.NewDecoder(reader).Decode(into) -} - -// Write writes JSON-encoded bytes into `writer` marshaled from `from` -func (*InvestigationJSONCodec) Write(writer io.Writer, from resource.Object) error { - return json.NewEncoder(writer).Encode(from) -} - -// Interface compliance checks -var _ resource.Codec = &InvestigationJSONCodec{} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_object_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_object_gen.go deleted file mode 100644 index eb819564176..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_object_gen.go +++ /dev/null @@ -1,319 +0,0 @@ -// -// Code generated by grafana-app-sdk. DO NOT EDIT. -// - -package v0alpha1 - -import ( - "fmt" - "github.com/grafana/grafana-app-sdk/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - "time" -) - -// +k8s:openapi-gen=true -type Investigation struct { - metav1.TypeMeta `json:",inline" yaml:",inline"` - metav1.ObjectMeta `json:"metadata" yaml:"metadata"` - - // Spec is the spec of the Investigation - Spec InvestigationSpec `json:"spec" yaml:"spec"` - - Status InvestigationStatus `json:"status" yaml:"status"` -} - -func (o *Investigation) GetSpec() any { - return o.Spec -} - -func (o *Investigation) SetSpec(spec any) error { - cast, ok := spec.(InvestigationSpec) - if !ok { - return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) - } - o.Spec = cast - return nil -} - -func (o *Investigation) GetSubresources() map[string]any { - return map[string]any{ - "status": o.Status, - } -} - -func (o *Investigation) GetSubresource(name string) (any, bool) { - switch name { - case "status": - return o.Status, true - default: - return nil, false - } -} - -func (o *Investigation) SetSubresource(name string, value any) error { - switch name { - case "status": - cast, ok := value.(InvestigationStatus) - if !ok { - return fmt.Errorf("cannot set status type %#v, not of type InvestigationStatus", value) - } - o.Status = cast - return nil - default: - return fmt.Errorf("subresource '%s' does not exist", name) - } -} - -func (o *Investigation) GetStaticMetadata() resource.StaticMetadata { - gvk := o.GroupVersionKind() - return resource.StaticMetadata{ - Name: o.ObjectMeta.Name, - Namespace: o.ObjectMeta.Namespace, - Group: gvk.Group, - Version: gvk.Version, - Kind: gvk.Kind, - } -} - -func (o *Investigation) SetStaticMetadata(metadata resource.StaticMetadata) { - o.Name = metadata.Name - o.Namespace = metadata.Namespace - o.SetGroupVersionKind(schema.GroupVersionKind{ - Group: metadata.Group, - Version: metadata.Version, - Kind: metadata.Kind, - }) -} - -func (o *Investigation) GetCommonMetadata() resource.CommonMetadata { - dt := o.DeletionTimestamp - var deletionTimestamp *time.Time - if dt != nil { - deletionTimestamp = &dt.Time - } - // Legacy ExtraFields support - extraFields := make(map[string]any) - if o.Annotations != nil { - extraFields["annotations"] = o.Annotations - } - if o.ManagedFields != nil { - extraFields["managedFields"] = o.ManagedFields - } - if o.OwnerReferences != nil { - extraFields["ownerReferences"] = o.OwnerReferences - } - return resource.CommonMetadata{ - UID: string(o.UID), - ResourceVersion: o.ResourceVersion, - Generation: o.Generation, - Labels: o.Labels, - CreationTimestamp: o.CreationTimestamp.Time, - DeletionTimestamp: deletionTimestamp, - Finalizers: o.Finalizers, - UpdateTimestamp: o.GetUpdateTimestamp(), - CreatedBy: o.GetCreatedBy(), - UpdatedBy: o.GetUpdatedBy(), - ExtraFields: extraFields, - } -} - -func (o *Investigation) SetCommonMetadata(metadata resource.CommonMetadata) { - o.UID = types.UID(metadata.UID) - o.ResourceVersion = metadata.ResourceVersion - o.Generation = metadata.Generation - o.Labels = metadata.Labels - o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp) - if metadata.DeletionTimestamp != nil { - dt := metav1.NewTime(*metadata.DeletionTimestamp) - o.DeletionTimestamp = &dt - } else { - o.DeletionTimestamp = nil - } - o.Finalizers = metadata.Finalizers - if o.Annotations == nil { - o.Annotations = make(map[string]string) - } - if !metadata.UpdateTimestamp.IsZero() { - o.SetUpdateTimestamp(metadata.UpdateTimestamp) - } - if metadata.CreatedBy != "" { - o.SetCreatedBy(metadata.CreatedBy) - } - if metadata.UpdatedBy != "" { - o.SetUpdatedBy(metadata.UpdatedBy) - } - // Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields - if metadata.ExtraFields != nil { - if annotations, ok := metadata.ExtraFields["annotations"]; ok { - if cast, ok := annotations.(map[string]string); ok { - o.Annotations = cast - } - } - if managedFields, ok := metadata.ExtraFields["managedFields"]; ok { - if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok { - o.ManagedFields = cast - } - } - if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok { - if cast, ok := ownerReferences.([]metav1.OwnerReference); ok { - o.OwnerReferences = cast - } - } - } -} - -func (o *Investigation) GetCreatedBy() string { - if o.ObjectMeta.Annotations == nil { - o.ObjectMeta.Annotations = make(map[string]string) - } - - return o.ObjectMeta.Annotations["grafana.com/createdBy"] -} - -func (o *Investigation) SetCreatedBy(createdBy string) { - if o.ObjectMeta.Annotations == nil { - o.ObjectMeta.Annotations = make(map[string]string) - } - - o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy -} - -func (o *Investigation) GetUpdateTimestamp() time.Time { - if o.ObjectMeta.Annotations == nil { - o.ObjectMeta.Annotations = make(map[string]string) - } - - parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"]) - return parsed -} - -func (o *Investigation) SetUpdateTimestamp(updateTimestamp time.Time) { - if o.ObjectMeta.Annotations == nil { - o.ObjectMeta.Annotations = make(map[string]string) - } - - o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) -} - -func (o *Investigation) GetUpdatedBy() string { - if o.ObjectMeta.Annotations == nil { - o.ObjectMeta.Annotations = make(map[string]string) - } - - return o.ObjectMeta.Annotations["grafana.com/updatedBy"] -} - -func (o *Investigation) SetUpdatedBy(updatedBy string) { - if o.ObjectMeta.Annotations == nil { - o.ObjectMeta.Annotations = make(map[string]string) - } - - o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy -} - -func (o *Investigation) Copy() resource.Object { - return resource.CopyObject(o) -} - -func (o *Investigation) DeepCopyObject() runtime.Object { - return o.Copy() -} - -func (o *Investigation) DeepCopy() *Investigation { - cpy := &Investigation{} - o.DeepCopyInto(cpy) - return cpy -} - -func (o *Investigation) DeepCopyInto(dst *Investigation) { - dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion - dst.TypeMeta.Kind = o.TypeMeta.Kind - o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta) - o.Spec.DeepCopyInto(&dst.Spec) - o.Status.DeepCopyInto(&dst.Status) -} - -// Interface compliance compile-time check -var _ resource.Object = &Investigation{} - -// +k8s:openapi-gen=true -type InvestigationList struct { - metav1.TypeMeta `json:",inline" yaml:",inline"` - metav1.ListMeta `json:"metadata" yaml:"metadata"` - Items []Investigation `json:"items" yaml:"items"` -} - -func (o *InvestigationList) DeepCopyObject() runtime.Object { - return o.Copy() -} - -func (o *InvestigationList) Copy() resource.ListObject { - cpy := &InvestigationList{ - TypeMeta: o.TypeMeta, - Items: make([]Investigation, len(o.Items)), - } - o.ListMeta.DeepCopyInto(&cpy.ListMeta) - for i := 0; i < len(o.Items); i++ { - if item, ok := o.Items[i].Copy().(*Investigation); ok { - cpy.Items[i] = *item - } - } - return cpy -} - -func (o *InvestigationList) GetItems() []resource.Object { - items := make([]resource.Object, len(o.Items)) - for i := 0; i < len(o.Items); i++ { - items[i] = &o.Items[i] - } - return items -} - -func (o *InvestigationList) SetItems(items []resource.Object) { - o.Items = make([]Investigation, len(items)) - for i := 0; i < len(items); i++ { - o.Items[i] = *items[i].(*Investigation) - } -} - -func (o *InvestigationList) DeepCopy() *InvestigationList { - cpy := &InvestigationList{} - o.DeepCopyInto(cpy) - return cpy -} - -func (o *InvestigationList) DeepCopyInto(dst *InvestigationList) { - resource.CopyObjectInto(dst, o) -} - -// Interface compliance compile-time check -var _ resource.ListObject = &InvestigationList{} - -// Copy methods for all subresource types - -// DeepCopy creates a full deep copy of Spec -func (s *InvestigationSpec) DeepCopy() *InvestigationSpec { - cpy := &InvestigationSpec{} - s.DeepCopyInto(cpy) - return cpy -} - -// DeepCopyInto deep copies Spec into another Spec object -func (s *InvestigationSpec) DeepCopyInto(dst *InvestigationSpec) { - resource.CopyObjectInto(dst, s) -} - -// DeepCopy creates a full deep copy of InvestigationStatus -func (s *InvestigationStatus) DeepCopy() *InvestigationStatus { - cpy := &InvestigationStatus{} - s.DeepCopyInto(cpy) - return cpy -} - -// DeepCopyInto deep copies InvestigationStatus into another InvestigationStatus object -func (s *InvestigationStatus) DeepCopyInto(dst *InvestigationStatus) { - resource.CopyObjectInto(dst, s) -} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_schema_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_schema_gen.go deleted file mode 100644 index 2a1f03c884a..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_schema_gen.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Code generated by grafana-app-sdk. DO NOT EDIT. -// - -package v0alpha1 - -import ( - "github.com/grafana/grafana-app-sdk/resource" -) - -// schema is unexported to prevent accidental overwrites -var ( - schemaInvestigation = resource.NewSimpleSchema("investigations.grafana.app", "v0alpha1", &Investigation{}, &InvestigationList{}, resource.WithKind("Investigation"), - resource.WithPlural("investigations"), resource.WithScope(resource.NamespacedScope)) - kindInvestigation = resource.Kind{ - Schema: schemaInvestigation, - Codecs: map[resource.KindEncoding]resource.Codec{ - resource.KindEncodingJSON: &InvestigationJSONCodec{}, - }, - } -) - -// Kind returns a resource.Kind for this Schema with a JSON codec -func InvestigationKind() resource.Kind { - return kindInvestigation -} - -// Schema returns a resource.SimpleSchema representation of Investigation -func InvestigationSchema() *resource.SimpleSchema { - return schemaInvestigation -} - -// Interface compliance checks -var _ resource.Schema = kindInvestigation diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_spec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_spec_gen.go deleted file mode 100644 index d56124603a2..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_spec_gen.go +++ /dev/null @@ -1,127 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -package v0alpha1 - -// Person represents a user profile with basic information -// +k8s:openapi-gen=true -type InvestigationPerson struct { - // Unique identifier for the user - Uid string `json:"uid"` - // Display name of the user - Name string `json:"name"` - // URL to user's Gravatar image - GravatarUrl string `json:"gravatarUrl"` -} - -// NewInvestigationPerson creates a new InvestigationPerson object. -func NewInvestigationPerson() *InvestigationPerson { - return &InvestigationPerson{} -} - -// Collectable represents an item collected during investigation -// +k8s:openapi-gen=true -type InvestigationCollectable struct { - Id string `json:"id"` - CreatedAt string `json:"createdAt"` - Title string `json:"title"` - Origin string `json:"origin"` - Type string `json:"type"` - // +listType=atomic - Queries []string `json:"queries"` - TimeRange InvestigationTimeRange `json:"timeRange"` - Datasource InvestigationDatasourceRef `json:"datasource"` - Url string `json:"url"` - LogoPath *string `json:"logoPath,omitempty"` - Note string `json:"note"` - NoteUpdatedAt string `json:"noteUpdatedAt"` - FieldConfig string `json:"fieldConfig"` -} - -// NewInvestigationCollectable creates a new InvestigationCollectable object. -func NewInvestigationCollectable() *InvestigationCollectable { - return &InvestigationCollectable{ - Queries: []string{}, - TimeRange: *NewInvestigationTimeRange(), - Datasource: *NewInvestigationDatasourceRef(), - } -} - -// TimeRange represents a time range with both absolute and relative values -// +k8s:openapi-gen=true -type InvestigationTimeRange struct { - From string `json:"from"` - To string `json:"to"` - Raw InvestigationV0alpha1TimeRangeRaw `json:"raw"` -} - -// NewInvestigationTimeRange creates a new InvestigationTimeRange object. -func NewInvestigationTimeRange() *InvestigationTimeRange { - return &InvestigationTimeRange{ - Raw: *NewInvestigationV0alpha1TimeRangeRaw(), - } -} - -// DatasourceRef is a reference to a datasource -// +k8s:openapi-gen=true -type InvestigationDatasourceRef struct { - Uid string `json:"uid"` -} - -// NewInvestigationDatasourceRef creates a new InvestigationDatasourceRef object. -func NewInvestigationDatasourceRef() *InvestigationDatasourceRef { - return &InvestigationDatasourceRef{} -} - -// +k8s:openapi-gen=true -type InvestigationViewMode struct { - Mode InvestigationViewModeMode `json:"mode"` - ShowComments bool `json:"showComments"` - ShowTooltips bool `json:"showTooltips"` -} - -// NewInvestigationViewMode creates a new InvestigationViewMode object. -func NewInvestigationViewMode() *InvestigationViewMode { - return &InvestigationViewMode{} -} - -// spec is the schema of our resource -// +k8s:openapi-gen=true -type InvestigationSpec struct { - Title string `json:"title"` - CreatedByProfile InvestigationPerson `json:"createdByProfile"` - HasCustomName bool `json:"hasCustomName"` - IsFavorite bool `json:"isFavorite"` - OverviewNote string `json:"overviewNote"` - OverviewNoteUpdatedAt string `json:"overviewNoteUpdatedAt"` - // +listType=atomic - Collectables []InvestigationCollectable `json:"collectables"` - ViewMode InvestigationViewMode `json:"viewMode"` -} - -// NewInvestigationSpec creates a new InvestigationSpec object. -func NewInvestigationSpec() *InvestigationSpec { - return &InvestigationSpec{ - CreatedByProfile: *NewInvestigationPerson(), - Collectables: []InvestigationCollectable{}, - ViewMode: *NewInvestigationViewMode(), - } -} - -// +k8s:openapi-gen=true -type InvestigationV0alpha1TimeRangeRaw struct { - From string `json:"from"` - To string `json:"to"` -} - -// NewInvestigationV0alpha1TimeRangeRaw creates a new InvestigationV0alpha1TimeRangeRaw object. -func NewInvestigationV0alpha1TimeRangeRaw() *InvestigationV0alpha1TimeRangeRaw { - return &InvestigationV0alpha1TimeRangeRaw{} -} - -// +k8s:openapi-gen=true -type InvestigationViewModeMode string - -const ( - InvestigationViewModeModeCompact InvestigationViewModeMode = "compact" - InvestigationViewModeModeFull InvestigationViewModeMode = "full" -) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_status_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_status_gen.go deleted file mode 100644 index c70224b96e4..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_status_gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -package v0alpha1 - -// +k8s:openapi-gen=true -type InvestigationstatusOperatorState struct { - // lastEvaluation is the ResourceVersion last evaluated - LastEvaluation string `json:"lastEvaluation"` - // state describes the state of the lastEvaluation. - // It is limited to three possible states for machine evaluation. - State InvestigationStatusOperatorStateState `json:"state"` - // descriptiveState is an optional more descriptive state field which has no requirements on format - DescriptiveState *string `json:"descriptiveState,omitempty"` - // details contains any extra information that is operator-specific - Details map[string]interface{} `json:"details,omitempty"` -} - -// NewInvestigationstatusOperatorState creates a new InvestigationstatusOperatorState object. -func NewInvestigationstatusOperatorState() *InvestigationstatusOperatorState { - return &InvestigationstatusOperatorState{} -} - -// +k8s:openapi-gen=true -type InvestigationStatus struct { - // operatorStates is a map of operator ID to operator state evaluations. - // Any operator which consumes this kind SHOULD add its state evaluation information to this field. - OperatorStates map[string]InvestigationstatusOperatorState `json:"operatorStates,omitempty"` - // additionalFields is reserved for future use - AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` -} - -// NewInvestigationStatus creates a new InvestigationStatus object. -func NewInvestigationStatus() *InvestigationStatus { - return &InvestigationStatus{} -} - -// +k8s:openapi-gen=true -type InvestigationStatusOperatorStateState string - -const ( - InvestigationStatusOperatorStateStateSuccess InvestigationStatusOperatorStateState = "success" - InvestigationStatusOperatorStateStateInProgress InvestigationStatusOperatorStateState = "in_progress" - InvestigationStatusOperatorStateStateFailed InvestigationStatusOperatorStateState = "failed" -) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_client_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_client_gen.go deleted file mode 100644 index 573d743b3cf..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_client_gen.go +++ /dev/null @@ -1,99 +0,0 @@ -package v0alpha1 - -import ( - "context" - - "github.com/grafana/grafana-app-sdk/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type InvestigationIndexClient struct { - client *resource.TypedClient[*InvestigationIndex, *InvestigationIndexList] -} - -func NewInvestigationIndexClient(client resource.Client) *InvestigationIndexClient { - return &InvestigationIndexClient{ - client: resource.NewTypedClient[*InvestigationIndex, *InvestigationIndexList](client, InvestigationIndexKind()), - } -} - -func NewInvestigationIndexClientFromGenerator(generator resource.ClientGenerator) (*InvestigationIndexClient, error) { - c, err := generator.ClientFor(InvestigationIndexKind()) - if err != nil { - return nil, err - } - return NewInvestigationIndexClient(c), nil -} - -func (c *InvestigationIndexClient) Get(ctx context.Context, identifier resource.Identifier) (*InvestigationIndex, error) { - return c.client.Get(ctx, identifier) -} - -func (c *InvestigationIndexClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*InvestigationIndexList, error) { - return c.client.List(ctx, namespace, opts) -} - -func (c *InvestigationIndexClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*InvestigationIndexList, error) { - resp, err := c.client.List(ctx, namespace, resource.ListOptions{ - ResourceVersion: opts.ResourceVersion, - Limit: opts.Limit, - LabelFilters: opts.LabelFilters, - FieldSelectors: opts.FieldSelectors, - }) - if err != nil { - return nil, err - } - for resp.GetContinue() != "" { - page, err := c.client.List(ctx, namespace, resource.ListOptions{ - Continue: resp.GetContinue(), - ResourceVersion: opts.ResourceVersion, - Limit: opts.Limit, - LabelFilters: opts.LabelFilters, - FieldSelectors: opts.FieldSelectors, - }) - if err != nil { - return nil, err - } - resp.SetContinue(page.GetContinue()) - resp.SetResourceVersion(page.GetResourceVersion()) - resp.SetItems(append(resp.GetItems(), page.GetItems()...)) - } - return resp, nil -} - -func (c *InvestigationIndexClient) Create(ctx context.Context, obj *InvestigationIndex, opts resource.CreateOptions) (*InvestigationIndex, error) { - // Make sure apiVersion and kind are set - obj.APIVersion = GroupVersion.Identifier() - obj.Kind = InvestigationIndexKind().Kind() - return c.client.Create(ctx, obj, opts) -} - -func (c *InvestigationIndexClient) Update(ctx context.Context, obj *InvestigationIndex, opts resource.UpdateOptions) (*InvestigationIndex, error) { - return c.client.Update(ctx, obj, opts) -} - -func (c *InvestigationIndexClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*InvestigationIndex, error) { - return c.client.Patch(ctx, identifier, req, opts) -} - -func (c *InvestigationIndexClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus InvestigationIndexStatus, opts resource.UpdateOptions) (*InvestigationIndex, error) { - return c.client.Update(ctx, &InvestigationIndex{ - TypeMeta: metav1.TypeMeta{ - Kind: InvestigationIndexKind().Kind(), - APIVersion: GroupVersion.Identifier(), - }, - ObjectMeta: metav1.ObjectMeta{ - ResourceVersion: opts.ResourceVersion, - Namespace: identifier.Namespace, - Name: identifier.Name, - }, - Status: newStatus, - }, resource.UpdateOptions{ - Subresource: "status", - ResourceVersion: opts.ResourceVersion, - }) -} - -func (c *InvestigationIndexClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error { - return c.client.Delete(ctx, identifier, opts) -} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_codec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_codec_gen.go deleted file mode 100644 index 0496ce4af6f..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_codec_gen.go +++ /dev/null @@ -1,28 +0,0 @@ -// -// Code generated by grafana-app-sdk. DO NOT EDIT. -// - -package v0alpha1 - -import ( - "encoding/json" - "io" - - "github.com/grafana/grafana-app-sdk/resource" -) - -// InvestigationIndexJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding -type InvestigationIndexJSONCodec struct{} - -// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` -func (*InvestigationIndexJSONCodec) Read(reader io.Reader, into resource.Object) error { - return json.NewDecoder(reader).Decode(into) -} - -// Write writes JSON-encoded bytes into `writer` marshaled from `from` -func (*InvestigationIndexJSONCodec) Write(writer io.Writer, from resource.Object) error { - return json.NewEncoder(writer).Encode(from) -} - -// Interface compliance checks -var _ resource.Codec = &InvestigationIndexJSONCodec{} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_metadata_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_metadata_gen.go deleted file mode 100644 index e7bef02a137..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_metadata_gen.go +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -package v0alpha1 - -import ( - time "time" -) - -// metadata contains embedded CommonMetadata and can be extended with custom string fields -// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here -// without external reference as using the CommonMetadata reference breaks thema codegen. -type InvestigationIndexMetadata struct { - UpdateTimestamp time.Time `json:"updateTimestamp"` - CreatedBy string `json:"createdBy"` - Uid string `json:"uid"` - CreationTimestamp time.Time `json:"creationTimestamp"` - DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` - Finalizers []string `json:"finalizers"` - ResourceVersion string `json:"resourceVersion"` - Generation int64 `json:"generation"` - UpdatedBy string `json:"updatedBy"` - Labels map[string]string `json:"labels"` -} - -// NewInvestigationIndexMetadata creates a new InvestigationIndexMetadata object. -func NewInvestigationIndexMetadata() *InvestigationIndexMetadata { - return &InvestigationIndexMetadata{ - Finalizers: []string{}, - Labels: map[string]string{}, - } -} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_schema_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_schema_gen.go deleted file mode 100644 index 3a0041dc6b8..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_schema_gen.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Code generated by grafana-app-sdk. DO NOT EDIT. -// - -package v0alpha1 - -import ( - "github.com/grafana/grafana-app-sdk/resource" -) - -// schema is unexported to prevent accidental overwrites -var ( - schemaInvestigationIndex = resource.NewSimpleSchema("investigations.grafana.app", "v0alpha1", &InvestigationIndex{}, &InvestigationIndexList{}, resource.WithKind("InvestigationIndex"), - resource.WithPlural("investigationindexes"), resource.WithScope(resource.NamespacedScope)) - kindInvestigationIndex = resource.Kind{ - Schema: schemaInvestigationIndex, - Codecs: map[resource.KindEncoding]resource.Codec{ - resource.KindEncodingJSON: &InvestigationIndexJSONCodec{}, - }, - } -) - -// Kind returns a resource.Kind for this Schema with a JSON codec -func InvestigationIndexKind() resource.Kind { - return kindInvestigationIndex -} - -// Schema returns a resource.SimpleSchema representation of InvestigationIndex -func InvestigationIndexSchema() *resource.SimpleSchema { - return schemaInvestigationIndex -} - -// Interface compliance checks -var _ resource.Schema = kindInvestigationIndex diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_spec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_spec_gen.go deleted file mode 100644 index 44be927c850..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_spec_gen.go +++ /dev/null @@ -1,94 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -package v0alpha1 - -// Person represents a user profile with basic information -// +k8s:openapi-gen=true -type InvestigationIndexPerson struct { - // Unique identifier for the user - Uid string `json:"uid"` - // Display name of the user - Name string `json:"name"` - // URL to user's Gravatar image - GravatarUrl string `json:"gravatarUrl"` -} - -// NewInvestigationIndexPerson creates a new InvestigationIndexPerson object. -func NewInvestigationIndexPerson() *InvestigationIndexPerson { - return &InvestigationIndexPerson{} -} - -// Type definition for investigation summaries -// +k8s:openapi-gen=true -type InvestigationIndexInvestigationSummary struct { - Title string `json:"title"` - CreatedByProfile InvestigationIndexPerson `json:"createdByProfile"` - HasCustomName bool `json:"hasCustomName"` - IsFavorite bool `json:"isFavorite"` - OverviewNote string `json:"overviewNote"` - OverviewNoteUpdatedAt string `json:"overviewNoteUpdatedAt"` - ViewMode InvestigationIndexViewMode `json:"viewMode"` - // +listType=atomic - CollectableSummaries []InvestigationIndexCollectableSummary `json:"collectableSummaries"` -} - -// NewInvestigationIndexInvestigationSummary creates a new InvestigationIndexInvestigationSummary object. -func NewInvestigationIndexInvestigationSummary() *InvestigationIndexInvestigationSummary { - return &InvestigationIndexInvestigationSummary{ - CreatedByProfile: *NewInvestigationIndexPerson(), - ViewMode: *NewInvestigationIndexViewMode(), - CollectableSummaries: []InvestigationIndexCollectableSummary{}, - } -} - -// +k8s:openapi-gen=true -type InvestigationIndexViewMode struct { - Mode InvestigationIndexViewModeMode `json:"mode"` - ShowComments bool `json:"showComments"` - ShowTooltips bool `json:"showTooltips"` -} - -// NewInvestigationIndexViewMode creates a new InvestigationIndexViewMode object. -func NewInvestigationIndexViewMode() *InvestigationIndexViewMode { - return &InvestigationIndexViewMode{} -} - -// +k8s:openapi-gen=true -type InvestigationIndexCollectableSummary struct { - Id string `json:"id"` - Title string `json:"title"` - LogoPath string `json:"logoPath"` - Origin string `json:"origin"` -} - -// NewInvestigationIndexCollectableSummary creates a new InvestigationIndexCollectableSummary object. -func NewInvestigationIndexCollectableSummary() *InvestigationIndexCollectableSummary { - return &InvestigationIndexCollectableSummary{} -} - -// +k8s:openapi-gen=true -type InvestigationIndexSpec struct { - // Title of the index, e.g. 'Favorites' or 'My Investigations' - Title string `json:"title"` - // The Person who owns this investigation index - Owner InvestigationIndexPerson `json:"owner"` - // Array of investigation summaries - // +listType=atomic - InvestigationSummaries []InvestigationIndexInvestigationSummary `json:"investigationSummaries"` -} - -// NewInvestigationIndexSpec creates a new InvestigationIndexSpec object. -func NewInvestigationIndexSpec() *InvestigationIndexSpec { - return &InvestigationIndexSpec{ - Owner: *NewInvestigationIndexPerson(), - InvestigationSummaries: []InvestigationIndexInvestigationSummary{}, - } -} - -// +k8s:openapi-gen=true -type InvestigationIndexViewModeMode string - -const ( - InvestigationIndexViewModeModeCompact InvestigationIndexViewModeMode = "compact" - InvestigationIndexViewModeModeFull InvestigationIndexViewModeMode = "full" -) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_status_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_status_gen.go deleted file mode 100644 index 455d39bdb48..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_status_gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -package v0alpha1 - -// +k8s:openapi-gen=true -type InvestigationIndexstatusOperatorState struct { - // lastEvaluation is the ResourceVersion last evaluated - LastEvaluation string `json:"lastEvaluation"` - // state describes the state of the lastEvaluation. - // It is limited to three possible states for machine evaluation. - State InvestigationIndexStatusOperatorStateState `json:"state"` - // descriptiveState is an optional more descriptive state field which has no requirements on format - DescriptiveState *string `json:"descriptiveState,omitempty"` - // details contains any extra information that is operator-specific - Details map[string]interface{} `json:"details,omitempty"` -} - -// NewInvestigationIndexstatusOperatorState creates a new InvestigationIndexstatusOperatorState object. -func NewInvestigationIndexstatusOperatorState() *InvestigationIndexstatusOperatorState { - return &InvestigationIndexstatusOperatorState{} -} - -// +k8s:openapi-gen=true -type InvestigationIndexStatus struct { - // operatorStates is a map of operator ID to operator state evaluations. - // Any operator which consumes this kind SHOULD add its state evaluation information to this field. - OperatorStates map[string]InvestigationIndexstatusOperatorState `json:"operatorStates,omitempty"` - // additionalFields is reserved for future use - AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` -} - -// NewInvestigationIndexStatus creates a new InvestigationIndexStatus object. -func NewInvestigationIndexStatus() *InvestigationIndexStatus { - return &InvestigationIndexStatus{} -} - -// +k8s:openapi-gen=true -type InvestigationIndexStatusOperatorStateState string - -const ( - InvestigationIndexStatusOperatorStateStateSuccess InvestigationIndexStatusOperatorStateState = "success" - InvestigationIndexStatusOperatorStateStateInProgress InvestigationIndexStatusOperatorStateState = "in_progress" - InvestigationIndexStatusOperatorStateStateFailed InvestigationIndexStatusOperatorStateState = "failed" -) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/zz_openapi_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/zz_openapi_gen.go deleted file mode 100644 index 4a095da63fc..00000000000 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/zz_openapi_gen.go +++ /dev/null @@ -1,1014 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// Code generated by grafana-app-sdk. DO NOT EDIT. - -package v0alpha1 - -import ( - common "k8s.io/kube-openapi/pkg/common" - spec "k8s.io/kube-openapi/pkg/validation/spec" -) - -func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { - return map[string]common.OpenAPIDefinition{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.Investigation": schema_pkg_apis_investigations_v0alpha1_Investigation(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationCollectable": schema_pkg_apis_investigations_v0alpha1_InvestigationCollectable(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationDatasourceRef": schema_pkg_apis_investigations_v0alpha1_InvestigationDatasourceRef(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndex": schema_pkg_apis_investigations_v0alpha1_InvestigationIndex(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexCollectableSummary": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexCollectableSummary(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexInvestigationSummary": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexInvestigationSummary(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexList": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexList(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexPerson(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexSpec": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexSpec(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexStatus": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexStatus(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexViewMode": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexViewMode(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexstatusOperatorState": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexstatusOperatorState(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationList": schema_pkg_apis_investigations_v0alpha1_InvestigationList(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationPerson": schema_pkg_apis_investigations_v0alpha1_InvestigationPerson(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationSpec": schema_pkg_apis_investigations_v0alpha1_InvestigationSpec(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationStatus": schema_pkg_apis_investigations_v0alpha1_InvestigationStatus(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationTimeRange": schema_pkg_apis_investigations_v0alpha1_InvestigationTimeRange(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationV0alpha1TimeRangeRaw": schema_pkg_apis_investigations_v0alpha1_InvestigationV0alpha1TimeRangeRaw(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationViewMode": schema_pkg_apis_investigations_v0alpha1_InvestigationViewMode(ref), - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationstatusOperatorState": schema_pkg_apis_investigations_v0alpha1_InvestigationstatusOperatorState(ref), - } -} - -func schema_pkg_apis_investigations_v0alpha1_Investigation(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Description: "Spec is the spec of the Investigation", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationStatus"), - }, - }, - }, - Required: []string{"metadata", "spec", "status"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationSpec", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationCollectable(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Collectable represents an item collected during investigation", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "id": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "createdAt": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "title": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "origin": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "type": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "queries": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - "timeRange": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationTimeRange"), - }, - }, - "datasource": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationDatasourceRef"), - }, - }, - "url": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "logoPath": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "note": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "noteUpdatedAt": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "fieldConfig": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"id", "createdAt", "title", "origin", "type", "queries", "timeRange", "datasource", "url", "note", "noteUpdatedAt", "fieldConfig"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationDatasourceRef", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationTimeRange"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationDatasourceRef(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DatasourceRef is a reference to a datasource", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "uid": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"uid"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndex(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Description: "Spec is the spec of the InvestigationIndex", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexStatus"), - }, - }, - }, - Required: []string{"metadata", "spec", "status"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexSpec", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexCollectableSummary(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "id": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "title": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "logoPath": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "origin": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"id", "title", "logoPath", "origin"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexInvestigationSummary(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Type definition for investigation summaries", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "title": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "createdByProfile": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson"), - }, - }, - "hasCustomName": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - "isFavorite": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - "overviewNote": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "overviewNoteUpdatedAt": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "viewMode": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexViewMode"), - }, - }, - "collectableSummaries": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexCollectableSummary"), - }, - }, - }, - }, - }, - }, - Required: []string{"title", "createdByProfile", "hasCustomName", "isFavorite", "overviewNote", "overviewNoteUpdatedAt", "viewMode", "collectableSummaries"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexCollectableSummary", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexViewMode"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndex"), - }, - }, - }, - }, - }, - }, - Required: []string{"metadata", "items"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndex", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexPerson(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Person represents a user profile with basic information", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "uid": { - SchemaProps: spec.SchemaProps{ - Description: "Unique identifier for the user", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Description: "Display name of the user", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "gravatarUrl": { - SchemaProps: spec.SchemaProps{ - Description: "URL to user's Gravatar image", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"uid", "name", "gravatarUrl"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "title": { - SchemaProps: spec.SchemaProps{ - Description: "Title of the index, e.g. 'Favorites' or 'My Investigations'", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "owner": { - SchemaProps: spec.SchemaProps{ - Description: "The Person who owns this investigation index", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson"), - }, - }, - "investigationSummaries": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Array of investigation summaries", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexInvestigationSummary"), - }, - }, - }, - }, - }, - }, - Required: []string{"title", "owner", "investigationSummaries"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexInvestigationSummary", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "operatorStates": { - SchemaProps: spec.SchemaProps{ - Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexstatusOperatorState"), - }, - }, - }, - }, - }, - "additionalFields": { - SchemaProps: spec.SchemaProps{ - Description: "additionalFields is reserved for future use", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexstatusOperatorState"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexViewMode(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "mode": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "showComments": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - "showTooltips": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - Required: []string{"mode", "showComments", "showTooltips"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "lastEvaluation": { - SchemaProps: spec.SchemaProps{ - Description: "lastEvaluation is the ResourceVersion last evaluated", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "state": { - SchemaProps: spec.SchemaProps{ - Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "descriptiveState": { - SchemaProps: spec.SchemaProps{ - Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", - Type: []string{"string"}, - Format: "", - }, - }, - "details": { - SchemaProps: spec.SchemaProps{ - Description: "details contains any extra information that is operator-specific", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - }, - Required: []string{"lastEvaluation", "state"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.Investigation"), - }, - }, - }, - }, - }, - }, - Required: []string{"metadata", "items"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.Investigation", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationPerson(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Person represents a user profile with basic information", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "uid": { - SchemaProps: spec.SchemaProps{ - Description: "Unique identifier for the user", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Description: "Display name of the user", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "gravatarUrl": { - SchemaProps: spec.SchemaProps{ - Description: "URL to user's Gravatar image", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"uid", "name", "gravatarUrl"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "spec is the schema of our resource", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "title": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "createdByProfile": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationPerson"), - }, - }, - "hasCustomName": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - "isFavorite": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - "overviewNote": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "overviewNoteUpdatedAt": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "collectables": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationCollectable"), - }, - }, - }, - }, - }, - "viewMode": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationViewMode"), - }, - }, - }, - Required: []string{"title", "createdByProfile", "hasCustomName", "isFavorite", "overviewNote", "overviewNoteUpdatedAt", "collectables", "viewMode"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationCollectable", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationPerson", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationViewMode"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "operatorStates": { - SchemaProps: spec.SchemaProps{ - Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationstatusOperatorState"), - }, - }, - }, - }, - }, - "additionalFields": { - SchemaProps: spec.SchemaProps{ - Description: "additionalFields is reserved for future use", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationstatusOperatorState"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationTimeRange(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "TimeRange represents a time range with both absolute and relative values", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "from": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "to": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "raw": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationV0alpha1TimeRangeRaw"), - }, - }, - }, - Required: []string{"from", "to", "raw"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationV0alpha1TimeRangeRaw"}, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationV0alpha1TimeRangeRaw(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "from": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "to": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"from", "to"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationViewMode(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "mode": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "showComments": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - "showTooltips": { - SchemaProps: spec.SchemaProps{ - Default: false, - Type: []string{"boolean"}, - Format: "", - }, - }, - }, - Required: []string{"mode", "showComments", "showTooltips"}, - }, - }, - } -} - -func schema_pkg_apis_investigations_v0alpha1_InvestigationstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "lastEvaluation": { - SchemaProps: spec.SchemaProps{ - Description: "lastEvaluation is the ResourceVersion last evaluated", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "state": { - SchemaProps: spec.SchemaProps{ - Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "descriptiveState": { - SchemaProps: spec.SchemaProps{ - Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", - Type: []string{"string"}, - Format: "", - }, - }, - "details": { - SchemaProps: spec.SchemaProps{ - Description: "details contains any extra information that is operator-specific", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - }, - Required: []string{"lastEvaluation", "state"}, - }, - }, - } -} diff --git a/apps/investigations/pkg/apis/investigations_manifest.go b/apps/investigations/pkg/apis/investigations_manifest.go deleted file mode 100644 index 2d3e9c7bdd3..00000000000 --- a/apps/investigations/pkg/apis/investigations_manifest.go +++ /dev/null @@ -1,136 +0,0 @@ -// -// This file is generated by grafana-app-sdk -// DO NOT EDIT -// - -package apis - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/grafana/grafana-app-sdk/app" - "github.com/grafana/grafana-app-sdk/resource" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/kube-openapi/pkg/spec3" - "k8s.io/kube-openapi/pkg/validation/spec" - - v0alpha1 "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1" -) - -var ( - rawSchemaInvestigationv0alpha1 = []byte(`{"Collectable":{"additionalProperties":false,"description":"Collectable represents an item collected during investigation","properties":{"createdAt":{"type":"string"},"datasource":{"$ref":"#/components/schemas/DatasourceRef"},"fieldConfig":{"type":"string"},"id":{"type":"string"},"logoPath":{"type":"string"},"note":{"type":"string"},"noteUpdatedAt":{"type":"string"},"origin":{"type":"string"},"queries":{"description":"+listType=atomic","items":{"type":"string"},"type":"array"},"timeRange":{"$ref":"#/components/schemas/TimeRange"},"title":{"type":"string"},"type":{"type":"string"},"url":{"type":"string"}},"required":["id","createdAt","title","origin","type","queries","timeRange","datasource","url","note","noteUpdatedAt","fieldConfig"],"type":"object"},"DatasourceRef":{"additionalProperties":false,"description":"DatasourceRef is a reference to a datasource","properties":{"uid":{"type":"string"}},"required":["uid"],"type":"object"},"Investigation":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"Person":{"additionalProperties":false,"description":"Person represents a user profile with basic information","properties":{"gravatarUrl":{"description":"URL to user's Gravatar image","type":"string"},"name":{"description":"Display name of the user","type":"string"},"uid":{"description":"Unique identifier for the user","type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"TimeRange":{"additionalProperties":false,"description":"TimeRange represents a time range with both absolute and relative values","properties":{"from":{"type":"string"},"raw":{"additionalProperties":false,"properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"type":"object"},"to":{"type":"string"}},"required":["from","to","raw"],"type":"object"},"ViewMode":{"additionalProperties":false,"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"},"spec":{"additionalProperties":false,"description":"spec is the schema of our resource","properties":{"collectables":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Collectable"},"type":"array"},"createdByProfile":{"$ref":"#/components/schemas/Person"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"$ref":"#/components/schemas/ViewMode"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","collectables","viewMode"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) - versionSchemaInvestigationv0alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaInvestigationv0alpha1, &versionSchemaInvestigationv0alpha1) - rawSchemaInvestigationIndexv0alpha1 = []byte(`{"CollectableSummary":{"additionalProperties":false,"properties":{"id":{"type":"string"},"logoPath":{"type":"string"},"origin":{"type":"string"},"title":{"type":"string"}},"required":["id","title","logoPath","origin"],"type":"object"},"InvestigationIndex":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"InvestigationSummary":{"additionalProperties":false,"description":"Type definition for investigation summaries","properties":{"collectableSummaries":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/CollectableSummary"},"type":"array"},"createdByProfile":{"$ref":"#/components/schemas/Person"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"$ref":"#/components/schemas/ViewMode"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","viewMode","collectableSummaries"],"type":"object"},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"Person":{"additionalProperties":false,"description":"Person represents a user profile with basic information","properties":{"gravatarUrl":{"description":"URL to user's Gravatar image","type":"string"},"name":{"description":"Display name of the user","type":"string"},"uid":{"description":"Unique identifier for the user","type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"ViewMode":{"additionalProperties":false,"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"investigationSummaries":{"description":"Array of investigation summaries\n+listType=atomic","items":{"$ref":"#/components/schemas/InvestigationSummary"},"type":"array"},"owner":{"$ref":"#/components/schemas/Person","description":"The Person who owns this investigation index"},"title":{"description":"Title of the index, e.g. 'Favorites' or 'My Investigations'","type":"string"}},"required":["title","owner","investigationSummaries"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) - versionSchemaInvestigationIndexv0alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaInvestigationIndexv0alpha1, &versionSchemaInvestigationIndexv0alpha1) -) - -var appManifestData = app.ManifestData{ - AppName: "investigations", - Group: "investigations.grafana.app", - PreferredVersion: "v0alpha1", - Versions: []app.ManifestVersion{ - { - Name: "v0alpha1", - Served: true, - Kinds: []app.ManifestVersionKind{ - { - Kind: "Investigation", - Plural: "Investigations", - Scope: "Namespaced", - Conversion: false, - Schema: &versionSchemaInvestigationv0alpha1, - }, - - { - Kind: "InvestigationIndex", - Plural: "InvestigationIndexes", - Scope: "Namespaced", - Conversion: false, - Schema: &versionSchemaInvestigationIndexv0alpha1, - }, - }, - Routes: app.ManifestVersionRoutes{ - Namespaced: map[string]spec3.PathProps{}, - Cluster: map[string]spec3.PathProps{}, - Schemas: map[string]spec.Schema{}, - }, - }, - }, -} - -func LocalManifest() app.Manifest { - return app.NewEmbeddedManifest(appManifestData) -} - -func RemoteManifest() app.Manifest { - return app.NewAPIServerManifest("investigations") -} - -var kindVersionToGoType = map[string]resource.Kind{ - "Investigation/v0alpha1": v0alpha1.InvestigationKind(), - "InvestigationIndex/v0alpha1": v0alpha1.InvestigationIndexKind(), -} - -// ManifestGoTypeAssociator returns the associated resource.Kind instance for a given Kind and Version, if one exists. -// If there is no association for the provided Kind and Version, exists will return false. -func ManifestGoTypeAssociator(kind, version string) (goType resource.Kind, exists bool) { - goType, exists = kindVersionToGoType[fmt.Sprintf("%s/%s", kind, version)] - return goType, exists -} - -var customRouteToGoResponseType = map[string]any{} - -// ManifestCustomRouteResponsesAssociator returns the associated response go type for a given kind, version, custom route path, and method, if one exists. -// kind may be empty for custom routes which are not kind subroutes. Leading slashes are removed from subroute paths. -// If there is no association for the provided kind, version, custom route path, and method, exists will return false. -// Resource routes (those without a kind) should prefix their route with "/" if the route is namespaced (otherwise the route is assumed to be cluster-scope) -func ManifestCustomRouteResponsesAssociator(kind, version, path, verb string) (goType any, exists bool) { - if len(path) > 0 && path[0] == '/' { - path = path[1:] - } - goType, exists = customRouteToGoResponseType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] - return goType, exists -} - -var customRouteToGoParamsType = map[string]runtime.Object{} - -func ManifestCustomRouteQueryAssociator(kind, version, path, verb string) (goType runtime.Object, exists bool) { - if len(path) > 0 && path[0] == '/' { - path = path[1:] - } - goType, exists = customRouteToGoParamsType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] - return goType, exists -} - -var customRouteToGoRequestBodyType = map[string]any{} - -func ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb string) (goType any, exists bool) { - if len(path) > 0 && path[0] == '/' { - path = path[1:] - } - goType, exists = customRouteToGoRequestBodyType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] - return goType, exists -} - -type GoTypeAssociator struct{} - -func NewGoTypeAssociator() *GoTypeAssociator { - return &GoTypeAssociator{} -} - -func (g *GoTypeAssociator) KindToGoType(kind, version string) (goType resource.Kind, exists bool) { - return ManifestGoTypeAssociator(kind, version) -} -func (g *GoTypeAssociator) CustomRouteReturnGoType(kind, version, path, verb string) (goType any, exists bool) { - return ManifestCustomRouteResponsesAssociator(kind, version, path, verb) -} -func (g *GoTypeAssociator) CustomRouteQueryGoType(kind, version, path, verb string) (goType runtime.Object, exists bool) { - return ManifestCustomRouteQueryAssociator(kind, version, path, verb) -} -func (g *GoTypeAssociator) CustomRouteRequestBodyGoType(kind, version, path, verb string) (goType any, exists bool) { - return ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb) -} diff --git a/apps/investigations/pkg/app/investigations_app.go b/apps/investigations/pkg/app/investigations_app.go deleted file mode 100644 index 516d278788d..00000000000 --- a/apps/investigations/pkg/app/investigations_app.go +++ /dev/null @@ -1,62 +0,0 @@ -package app - -import ( - "context" - - "github.com/grafana/grafana-app-sdk/app" - "github.com/grafana/grafana-app-sdk/operator" - "github.com/grafana/grafana-app-sdk/resource" - "github.com/grafana/grafana-app-sdk/simple" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/klog/v2" - - investigationsv0alpha1 "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1" -) - -func New(cfg app.Config) (app.App, error) { - var err error - simpleConfig := simple.AppConfig{ - Name: "investigation", - KubeConfig: cfg.KubeConfig, - InformerConfig: simple.AppInformerConfig{ - InformerOptions: operator.InformerOptions{ - ErrorHandler: func(_ context.Context, err error) { - klog.ErrorS(err, "Informer processing error") - }, - }, - }, - ManagedKinds: []simple.AppManagedKind{ - { - Kind: investigationsv0alpha1.InvestigationKind(), - }, - { - Kind: investigationsv0alpha1.InvestigationIndexKind(), - }, - }, - } - - a, err := simple.NewApp(simpleConfig) - if err != nil { - return nil, err - } - - err = a.ValidateManifest(cfg.ManifestData) - if err != nil { - return nil, err - } - - return a, nil -} - -func GetKinds() map[schema.GroupVersion][]resource.Kind { - gv := schema.GroupVersion{ - Group: investigationsv0alpha1.InvestigationKind().Group(), - Version: investigationsv0alpha1.InvestigationKind().Version(), - } - return map[schema.GroupVersion][]resource.Kind{ - gv: { - investigationsv0alpha1.InvestigationKind(), - investigationsv0alpha1.InvestigationIndexKind(), - }, - } -} diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.spec.gen.ts b/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.spec.gen.ts deleted file mode 100644 index c46622cd502..00000000000 --- a/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.spec.gen.ts +++ /dev/null @@ -1,115 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -// Person represents a user profile with basic information -export interface Person { - // Unique identifier for the user - uid: string; - // Display name of the user - name: string; - // URL to user's Gravatar image - gravatarUrl: string; -} - -export const defaultPerson = (): Person => ({ - uid: "", - name: "", - gravatarUrl: "", -}); - -// Collectable represents an item collected during investigation -export interface Collectable { - id: string; - createdAt: string; - title: string; - origin: string; - type: string; - // +listType=atomic - queries: string[]; - timeRange: TimeRange; - datasource: DatasourceRef; - url: string; - logoPath?: string; - note: string; - noteUpdatedAt: string; - fieldConfig: string; -} - -export const defaultCollectable = (): Collectable => ({ - id: "", - createdAt: "", - title: "", - origin: "", - type: "", - queries: [], - timeRange: defaultTimeRange(), - datasource: defaultDatasourceRef(), - url: "", - note: "", - noteUpdatedAt: "", - fieldConfig: "", -}); - -// TimeRange represents a time range with both absolute and relative values -export interface TimeRange { - from: string; - to: string; - raw: { - from: string; - to: string; - }; -} - -export const defaultTimeRange = (): TimeRange => ({ - from: "", - to: "", - raw: { - from: "", - to: "", -}, -}); - -// DatasourceRef is a reference to a datasource -export interface DatasourceRef { - uid: string; -} - -export const defaultDatasourceRef = (): DatasourceRef => ({ - uid: "", -}); - -export interface ViewMode { - mode: "compact" | "full"; - showComments: boolean; - showTooltips: boolean; -} - -export const defaultViewMode = (): ViewMode => ({ - mode: "compact", - showComments: false, - showTooltips: false, -}); - -// spec is the schema of our resource -export interface Spec { - title: string; - createdByProfile: Person; - hasCustomName: boolean; - isFavorite: boolean; - overviewNote: string; - overviewNoteUpdatedAt: string; - // +listType=atomic - collectables: Collectable[]; - viewMode: ViewMode; -} - -export const defaultSpec = (): Spec => ({ - title: "", - createdByProfile: defaultPerson(), - hasCustomName: false, - isFavorite: false, - overviewNote: "", - overviewNoteUpdatedAt: "", - collectables: [], - viewMode: defaultViewMode(), -}); - diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.spec.gen.ts b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.spec.gen.ts deleted file mode 100644 index f0d2f25d96b..00000000000 --- a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.spec.gen.ts +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -// Person represents a user profile with basic information -export interface Person { - // Unique identifier for the user - uid: string; - // Display name of the user - name: string; - // URL to user's Gravatar image - gravatarUrl: string; -} - -export const defaultPerson = (): Person => ({ - uid: "", - name: "", - gravatarUrl: "", -}); - -// Type definition for investigation summaries -export interface InvestigationSummary { - title: string; - createdByProfile: Person; - hasCustomName: boolean; - isFavorite: boolean; - overviewNote: string; - overviewNoteUpdatedAt: string; - viewMode: ViewMode; - // +listType=atomic - collectableSummaries: CollectableSummary[]; -} - -export const defaultInvestigationSummary = (): InvestigationSummary => ({ - title: "", - createdByProfile: defaultPerson(), - hasCustomName: false, - isFavorite: false, - overviewNote: "", - overviewNoteUpdatedAt: "", - viewMode: defaultViewMode(), - collectableSummaries: [], -}); - -export interface ViewMode { - mode: "compact" | "full"; - showComments: boolean; - showTooltips: boolean; -} - -export const defaultViewMode = (): ViewMode => ({ - mode: "compact", - showComments: false, - showTooltips: false, -}); - -export interface CollectableSummary { - id: string; - title: string; - logoPath: string; - origin: string; -} - -export const defaultCollectableSummary = (): CollectableSummary => ({ - id: "", - title: "", - logoPath: "", - origin: "", -}); - -export interface Spec { - // Title of the index, e.g. 'Favorites' or 'My Investigations' - title: string; - // The Person who owns this investigation index - owner: Person; - // Array of investigation summaries - // +listType=atomic - investigationSummaries: InvestigationSummary[]; -} - -export const defaultSpec = (): Spec => ({ - title: "", - owner: defaultPerson(), - investigationSummaries: [], -}); - diff --git a/apps/logsdrilldown/definitions/logsdrilldown-manifest.json b/apps/logsdrilldown/definitions/logsdrilldown-manifest.json new file mode 100644 index 00000000000..3ef92d3d5b8 --- /dev/null +++ b/apps/logsdrilldown/definitions/logsdrilldown-manifest.json @@ -0,0 +1,325 @@ +{ + "apiVersion": "apps.grafana.com/v1alpha2", + "kind": "AppManifest", + "metadata": { + "name": "logsdrilldown" + }, + "spec": { + "appName": "logsdrilldown", + "group": "logsdrilldown.grafana.app", + "versions": [ + { + "name": "v1alpha1", + "served": true, + "kinds": [ + { + "kind": "LogsDrilldown", + "plural": "LogsDrilldowns", + "scope": "Namespaced", + "schemas": { + "LogsDrilldown": { + "properties": { + "spec": { + "$ref": "#/components/schemas/spec" + }, + "status": { + "$ref": "#/components/schemas/status" + } + }, + "required": ["spec"] + }, + "OperatorState": { + "additionalProperties": false, + "properties": { + "descriptiveState": { + "description": "descriptiveState is an optional more descriptive state field which has no requirements on format", + "type": "string" + }, + "details": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "description": "details contains any extra information that is operator-specific", + "type": "object" + }, + "lastEvaluation": { + "description": "lastEvaluation is the ResourceVersion last evaluated", + "type": "string" + }, + "state": { + "description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.", + "enum": ["success", "in_progress", "failed"], + "type": "string" + } + }, + "required": ["lastEvaluation", "state"], + "type": "object" + }, + "spec": { + "additionalProperties": false, + "properties": { + "defaultFields": { + "items": { + "type": "string" + }, + "type": "array" + }, + "interceptDismissed": { + "type": "boolean" + }, + "prettifyJSON": { + "type": "boolean" + }, + "wrapLogMessage": { + "type": "boolean" + } + }, + "required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"], + "type": "object" + }, + "status": { + "additionalProperties": false, + "properties": { + "additionalFields": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "description": "additionalFields is reserved for future use", + "type": "object" + }, + "operatorStates": { + "additionalProperties": { + "$ref": "#/components/schemas/OperatorState" + }, + "description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.", + "type": "object" + } + }, + "type": "object" + } + }, + "conversion": false + }, + { + "kind": "LogsDrilldownDefaults", + "plural": "LogsDrilldownDefaults", + "scope": "Namespaced", + "schemas": { + "LogsDrilldownDefaults": { + "properties": { + "spec": { + "$ref": "#/components/schemas/spec" + }, + "status": { + "$ref": "#/components/schemas/status" + } + }, + "required": ["spec"] + }, + "OperatorState": { + "additionalProperties": false, + "properties": { + "descriptiveState": { + "description": "descriptiveState is an optional more descriptive state field which has no requirements on format", + "type": "string" + }, + "details": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "description": "details contains any extra information that is operator-specific", + "type": "object" + }, + "lastEvaluation": { + "description": "lastEvaluation is the ResourceVersion last evaluated", + "type": "string" + }, + "state": { + "description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.", + "enum": ["success", "in_progress", "failed"], + "type": "string" + } + }, + "required": ["lastEvaluation", "state"], + "type": "object" + }, + "spec": { + "additionalProperties": false, + "properties": { + "defaultFields": { + "items": { + "type": "string" + }, + "type": "array" + }, + "interceptDismissed": { + "type": "boolean" + }, + "prettifyJSON": { + "type": "boolean" + }, + "wrapLogMessage": { + "type": "boolean" + } + }, + "required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"], + "type": "object" + }, + "status": { + "additionalProperties": false, + "properties": { + "additionalFields": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "description": "additionalFields is reserved for future use", + "type": "object" + }, + "operatorStates": { + "additionalProperties": { + "$ref": "#/components/schemas/OperatorState" + }, + "description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.", + "type": "object" + } + }, + "type": "object" + } + }, + "conversion": false + } + ] + }, + { + "name": "v1beta1", + "served": true, + "kinds": [ + { + "kind": "LogsDrilldownDefaultColumns", + "plural": "LogsDrilldownDefaultColumns", + "scope": "Namespaced", + "schemas": { + "LogsDefaultColumnsLabel": { + "additionalProperties": false, + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["key", "value"], + "type": "object" + }, + "LogsDefaultColumnsLabels": { + "items": { + "$ref": "#/components/schemas/LogsDefaultColumnsLabel" + }, + "type": "array" + }, + "LogsDefaultColumnsRecord": { + "additionalProperties": false, + "properties": { + "columns": { + "items": { + "type": "string" + }, + "type": "array" + }, + "labels": { + "$ref": "#/components/schemas/LogsDefaultColumnsLabels" + } + }, + "required": ["columns", "labels"], + "type": "object" + }, + "LogsDefaultColumnsRecords": { + "items": { + "$ref": "#/components/schemas/LogsDefaultColumnsRecord" + }, + "type": "array" + }, + "LogsDrilldownDefaultColumns": { + "properties": { + "spec": { + "$ref": "#/components/schemas/spec" + }, + "status": { + "$ref": "#/components/schemas/status" + } + }, + "required": ["spec"] + }, + "OperatorState": { + "additionalProperties": false, + "properties": { + "descriptiveState": { + "description": "descriptiveState is an optional more descriptive state field which has no requirements on format", + "type": "string" + }, + "details": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "description": "details contains any extra information that is operator-specific", + "type": "object" + }, + "lastEvaluation": { + "description": "lastEvaluation is the ResourceVersion last evaluated", + "type": "string" + }, + "state": { + "description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.", + "enum": ["success", "in_progress", "failed"], + "type": "string" + } + }, + "required": ["lastEvaluation", "state"], + "type": "object" + }, + "spec": { + "additionalProperties": false, + "properties": { + "records": { + "$ref": "#/components/schemas/LogsDefaultColumnsRecords" + } + }, + "required": ["records"], + "type": "object" + }, + "status": { + "additionalProperties": false, + "properties": { + "additionalFields": { + "additionalProperties": { + "additionalProperties": {}, + "type": "object" + }, + "description": "additionalFields is reserved for future use", + "type": "object" + }, + "operatorStates": { + "additionalProperties": { + "$ref": "#/components/schemas/OperatorState" + }, + "description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.", + "type": "object" + } + }, + "type": "object" + } + }, + "conversion": false + } + ] + } + ], + "preferredVersion": "v1beta1" + } +} diff --git a/apps/logsdrilldown/definitions/logsdrilldown.logsdrilldown.grafana.app.json b/apps/logsdrilldown/definitions/logsdrilldown.logsdrilldown.grafana.app.json new file mode 100644 index 00000000000..e0259f421ad --- /dev/null +++ b/apps/logsdrilldown/definitions/logsdrilldown.logsdrilldown.grafana.app.json @@ -0,0 +1,92 @@ +{ + "kind": "CustomResourceDefinition", + "apiVersion": "apiextensions.k8s.io/v1", + "metadata": { + "name": "logsdrilldowns.logsdrilldown.grafana.app" + }, + "spec": { + "group": "logsdrilldown.grafana.app", + "versions": [ + { + "name": "v1alpha1", + "served": true, + "storage": true, + "schema": { + "openAPIV3Schema": { + "properties": { + "spec": { + "properties": { + "defaultFields": { + "items": { + "type": "string" + }, + "type": "array" + }, + "interceptDismissed": { + "type": "boolean" + }, + "prettifyJSON": { + "type": "boolean" + }, + "wrapLogMessage": { + "type": "boolean" + } + }, + "required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"], + "type": "object" + }, + "status": { + "properties": { + "additionalFields": { + "description": "additionalFields is reserved for future use", + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "operatorStates": { + "additionalProperties": { + "properties": { + "descriptiveState": { + "description": "descriptiveState is an optional more descriptive state field which has no requirements on format", + "type": "string" + }, + "details": { + "description": "details contains any extra information that is operator-specific", + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "lastEvaluation": { + "description": "lastEvaluation is the ResourceVersion last evaluated", + "type": "string" + }, + "state": { + "description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.", + "enum": ["success", "in_progress", "failed"], + "type": "string" + } + }, + "required": ["lastEvaluation", "state"], + "type": "object" + }, + "description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.", + "type": "object" + } + }, + "type": "object" + } + }, + "required": ["spec"], + "type": "object" + } + }, + "subresources": { + "status": {} + } + } + ], + "names": { + "kind": "LogsDrilldown", + "plural": "logsdrilldowns" + }, + "scope": "Namespaced" + } +} diff --git a/apps/logsdrilldown/definitions/logsdrilldowndefaultcolumns.logsdrilldown.grafana.app.json b/apps/logsdrilldown/definitions/logsdrilldowndefaultcolumns.logsdrilldown.grafana.app.json new file mode 100644 index 00000000000..c8987741983 --- /dev/null +++ b/apps/logsdrilldown/definitions/logsdrilldowndefaultcolumns.logsdrilldown.grafana.app.json @@ -0,0 +1,107 @@ +{ + "kind": "CustomResourceDefinition", + "apiVersion": "apiextensions.k8s.io/v1", + "metadata": { + "name": "logsdrilldowndefaultcolumns.logsdrilldown.grafana.app" + }, + "spec": { + "group": "logsdrilldown.grafana.app", + "versions": [ + { + "name": "v1beta1", + "served": true, + "storage": true, + "schema": { + "openAPIV3Schema": { + "properties": { + "spec": { + "properties": { + "records": { + "items": { + "properties": { + "columns": { + "items": { + "type": "string" + }, + "type": "array" + }, + "labels": { + "items": { + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["key", "value"], + "type": "object" + }, + "type": "array" + } + }, + "required": ["columns", "labels"], + "type": "object" + }, + "type": "array" + } + }, + "required": ["records"], + "type": "object" + }, + "status": { + "properties": { + "additionalFields": { + "description": "additionalFields is reserved for future use", + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "operatorStates": { + "additionalProperties": { + "properties": { + "descriptiveState": { + "description": "descriptiveState is an optional more descriptive state field which has no requirements on format", + "type": "string" + }, + "details": { + "description": "details contains any extra information that is operator-specific", + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "lastEvaluation": { + "description": "lastEvaluation is the ResourceVersion last evaluated", + "type": "string" + }, + "state": { + "description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.", + "enum": ["success", "in_progress", "failed"], + "type": "string" + } + }, + "required": ["lastEvaluation", "state"], + "type": "object" + }, + "description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.", + "type": "object" + } + }, + "type": "object" + } + }, + "required": ["spec"], + "type": "object" + } + }, + "subresources": { + "status": {} + } + } + ], + "names": { + "kind": "LogsDrilldownDefaultColumns", + "plural": "logsdrilldowndefaultcolumns" + }, + "scope": "Namespaced" + } +} diff --git a/apps/logsdrilldown/definitions/logsdrilldowndefaults.logsdrilldown.grafana.app.json b/apps/logsdrilldown/definitions/logsdrilldowndefaults.logsdrilldown.grafana.app.json new file mode 100644 index 00000000000..f2ab4b77e80 --- /dev/null +++ b/apps/logsdrilldown/definitions/logsdrilldowndefaults.logsdrilldown.grafana.app.json @@ -0,0 +1,92 @@ +{ + "kind": "CustomResourceDefinition", + "apiVersion": "apiextensions.k8s.io/v1", + "metadata": { + "name": "logsdrilldowndefaults.logsdrilldown.grafana.app" + }, + "spec": { + "group": "logsdrilldown.grafana.app", + "versions": [ + { + "name": "v1alpha1", + "served": true, + "storage": true, + "schema": { + "openAPIV3Schema": { + "properties": { + "spec": { + "properties": { + "defaultFields": { + "items": { + "type": "string" + }, + "type": "array" + }, + "interceptDismissed": { + "type": "boolean" + }, + "prettifyJSON": { + "type": "boolean" + }, + "wrapLogMessage": { + "type": "boolean" + } + }, + "required": ["defaultFields", "prettifyJSON", "wrapLogMessage", "interceptDismissed"], + "type": "object" + }, + "status": { + "properties": { + "additionalFields": { + "description": "additionalFields is reserved for future use", + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "operatorStates": { + "additionalProperties": { + "properties": { + "descriptiveState": { + "description": "descriptiveState is an optional more descriptive state field which has no requirements on format", + "type": "string" + }, + "details": { + "description": "details contains any extra information that is operator-specific", + "type": "object", + "x-kubernetes-preserve-unknown-fields": true + }, + "lastEvaluation": { + "description": "lastEvaluation is the ResourceVersion last evaluated", + "type": "string" + }, + "state": { + "description": "state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.", + "enum": ["success", "in_progress", "failed"], + "type": "string" + } + }, + "required": ["lastEvaluation", "state"], + "type": "object" + }, + "description": "operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.", + "type": "object" + } + }, + "type": "object" + } + }, + "required": ["spec"], + "type": "object" + } + }, + "subresources": { + "status": {} + } + } + ], + "names": { + "kind": "LogsDrilldownDefaults", + "plural": "logsdrilldowndefaults" + }, + "scope": "Namespaced" + } +} diff --git a/apps/logsdrilldown/go.mod b/apps/logsdrilldown/go.mod index 2a35278d19a..e210773eb2e 100644 --- a/apps/logsdrilldown/go.mod +++ b/apps/logsdrilldown/go.mod @@ -3,15 +3,15 @@ module github.com/grafana/grafana/apps/logsdrilldown go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -21,13 +21,23 @@ require ( github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -36,7 +46,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -49,43 +59,43 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/logsdrilldown/go.sum b/apps/logsdrilldown/go.sum index 3df8e8b5ebe..e5233ba82c9 100644 --- a/apps/logsdrilldown/go.sum +++ b/apps/logsdrilldown/go.sum @@ -1,7 +1,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -23,14 +23,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -39,8 +65,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -48,10 +74,10 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -73,8 +99,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -95,8 +121,6 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -104,10 +128,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -122,30 +146,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -163,34 +187,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -199,39 +223,39 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/logsdrilldown/kinds/logsdrilldown.cue b/apps/logsdrilldown/kinds/logsdrilldown.cue index 4a560ae3c6e..4b2d815743d 100644 --- a/apps/logsdrilldown/kinds/logsdrilldown.cue +++ b/apps/logsdrilldown/kinds/logsdrilldown.cue @@ -1,5 +1,9 @@ package kinds +import ( + "github.com/grafana/grafana/apps/logsdrilldown/kinds/v1beta1", +) + LogsDrilldownSpecv1alpha1: { defaultFields: [...string] | *[] prettifyJSON: bool @@ -21,3 +25,12 @@ logsdrilldownDefaultsv1alpha1: { spec: LogsDrilldownSpecv1alpha1 } } + +// Default columns API (beta) +logsdrilldownDefaultColumnsv1beta1: { + kind: "LogsDrilldownDefaultColumns" + pluralName: "LogsDrilldownDefaultColumns" + schema: { + spec: v1beta1.LogsDefaultColumns + } +} diff --git a/apps/logsdrilldown/kinds/manifest.cue b/apps/logsdrilldown/kinds/manifest.cue index e2f2fb236b1..cbd47ce2b65 100644 --- a/apps/logsdrilldown/kinds/manifest.cue +++ b/apps/logsdrilldown/kinds/manifest.cue @@ -15,6 +15,7 @@ manifest: { // If your app needs access to kinds managed by another app, use permissions.accessKinds to allow your app access. versions: { "v1alpha1": v1alpha1 + "v1beta1" : v1beta1 } // extraPermissions contains any additional permissions your app may require to function. // Your app will always have all permissions for each kind it manages (the items defined in 'kinds'). @@ -40,7 +41,7 @@ v1alpha1: { // served indicates whether this particular version is served by the API server. // served should be set to false before a version is removed from the manifest entirely. // served defaults to true if not present. - served: true + served: true // [OPTIONAL] // Codegen is a trait that tells the grafana-app-sdk, or other code generation tooling, how to process this kind. // If not present, default values within the codegen trait are used. @@ -64,4 +65,37 @@ v1alpha1: { enabled: true } } -} \ No newline at end of file +} + +v1beta1: { + // kinds is the list of kinds served by this version + kinds: [logsdrilldownDefaultColumnsv1beta1] + // [OPTIONAL] + // served indicates whether this particular version is served by the API server. + // served should be set to false before a version is removed from the manifest entirely. + // served defaults to true if not present. + served: true + // [OPTIONAL] + // Codegen is a trait that tells the grafana-app-sdk, or other code generation tooling, how to process this kind. + // If not present, default values within the codegen trait are used. + // If you wish to specify codegen per-version, put this section in the version's object + // (for example, v1alpha1) instead. + codegen: { + // [OPTIONAL] + // ts contains TypeScript code generation properties for the kind + ts: { + // [OPTIONAL] + // enabled indicates whether the CLI should generate front-end TypeScript code for the kind. + // Defaults to true if not present. + enabled: true + } + // [OPTIONAL] + // go contains go code generation properties for the kind + go: { + // [OPTIONAL] + // enabled indicates whether the CLI should generate back-end go code for the kind. + // Defaults to true if not present. + enabled: true + } + } +} diff --git a/apps/logsdrilldown/kinds/v0alpha1/defaultcolumns.cue b/apps/logsdrilldown/kinds/v0alpha1/defaultcolumns.cue new file mode 100644 index 00000000000..123d5129c15 --- /dev/null +++ b/apps/logsdrilldown/kinds/v0alpha1/defaultcolumns.cue @@ -0,0 +1,19 @@ +package v0alpha1 + +#LogsDefaultColumnsLabel: { + key: string + value: string +} + +#LogsDefaultColumnsLabels: [...#LogsDefaultColumnsLabel] + +#LogsDefaultColumnsRecord: { + columns: [...string] + labels: #LogsDefaultColumnsLabels +} + +#LogsDefaultColumnsRecords: [...#LogsDefaultColumnsRecord] + +LogsDefaultColumns: { + records: #LogsDefaultColumnsRecords +} diff --git a/apps/logsdrilldown/kinds/v1beta1/defaultcolumns.cue b/apps/logsdrilldown/kinds/v1beta1/defaultcolumns.cue new file mode 100644 index 00000000000..a66e813766b --- /dev/null +++ b/apps/logsdrilldown/kinds/v1beta1/defaultcolumns.cue @@ -0,0 +1,19 @@ +package v1beta1 + +#LogsDefaultColumnsLabel: { + key: string + value: string +} + +#LogsDefaultColumnsLabels: [...#LogsDefaultColumnsLabel] + +#LogsDefaultColumnsRecord: { + columns: [...string] + labels: #LogsDefaultColumnsLabels +} + +#LogsDefaultColumnsRecords: [...#LogsDefaultColumnsRecord] + +LogsDefaultColumns: { + records: #LogsDefaultColumnsRecords +} diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_object_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_object_gen.go index 4ede8bb4ee6..50bdc230cd1 100644 --- a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_object_gen.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_object_gen.go @@ -25,6 +25,13 @@ type LogsDrilldown struct { Status LogsDrilldownStatus `json:"status" yaml:"status"` } +func NewLogsDrilldown() *LogsDrilldown { + return &LogsDrilldown{ + Spec: *NewLogsDrilldownSpec(), + Status: *NewLogsDrilldownStatus(), + } +} + func (o *LogsDrilldown) GetSpec() any { return o.Spec } diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_schema_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_schema_gen.go index e6864c965a7..8e88e870346 100644 --- a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_schema_gen.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldown_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaLogsDrilldown = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", &LogsDrilldown{}, &LogsDrilldownList{}, resource.WithKind("LogsDrilldown"), + schemaLogsDrilldown = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", NewLogsDrilldown(), &LogsDrilldownList{}, resource.WithKind("LogsDrilldown"), resource.WithPlural("logsdrilldowns"), resource.WithScope(resource.NamespacedScope)) kindLogsDrilldown = resource.Kind{ Schema: schemaLogsDrilldown, diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_object_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_object_gen.go index 8dfb90a1bfb..ff5ce10adce 100644 --- a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_object_gen.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_object_gen.go @@ -25,6 +25,13 @@ type LogsDrilldownDefaults struct { Status LogsDrilldownDefaultsStatus `json:"status" yaml:"status"` } +func NewLogsDrilldownDefaults() *LogsDrilldownDefaults { + return &LogsDrilldownDefaults{ + Spec: *NewLogsDrilldownDefaultsSpec(), + Status: *NewLogsDrilldownDefaultsStatus(), + } +} + func (o *LogsDrilldownDefaults) GetSpec() any { return o.Spec } diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_schema_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_schema_gen.go index 20e952ce021..f488c319db2 100644 --- a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_schema_gen.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1/logsdrilldowndefaults_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaLogsDrilldownDefaults = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", &LogsDrilldownDefaults{}, &LogsDrilldownDefaultsList{}, resource.WithKind("LogsDrilldownDefaults"), + schemaLogsDrilldownDefaults = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1alpha1", NewLogsDrilldownDefaults(), &LogsDrilldownDefaultsList{}, resource.WithKind("LogsDrilldownDefaults"), resource.WithPlural("logsdrilldowndefaults"), resource.WithScope(resource.NamespacedScope)) kindLogsDrilldownDefaults = resource.Kind{ Schema: schemaLogsDrilldownDefaults, diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/constants.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/constants.go similarity index 82% rename from apps/investigations/pkg/apis/investigations/v0alpha1/constants.go rename to apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/constants.go index bd538eb9c30..ecfc11a456f 100644 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/constants.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/constants.go @@ -1,12 +1,12 @@ -package v0alpha1 +package v1beta1 import "k8s.io/apimachinery/pkg/runtime/schema" const ( // APIGroup is the API group used by all kinds in this package - APIGroup = "investigations.grafana.app" + APIGroup = "logsdrilldown.grafana.app" // APIVersion is the API version used by all kinds in this package - APIVersion = "v0alpha1" + APIVersion = "v1beta1" ) var ( diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_client_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_client_gen.go new file mode 100644 index 00000000000..856c3af291b --- /dev/null +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_client_gen.go @@ -0,0 +1,99 @@ +package v1beta1 + +import ( + "context" + + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type LogsDrilldownDefaultColumnsClient struct { + client *resource.TypedClient[*LogsDrilldownDefaultColumns, *LogsDrilldownDefaultColumnsList] +} + +func NewLogsDrilldownDefaultColumnsClient(client resource.Client) *LogsDrilldownDefaultColumnsClient { + return &LogsDrilldownDefaultColumnsClient{ + client: resource.NewTypedClient[*LogsDrilldownDefaultColumns, *LogsDrilldownDefaultColumnsList](client, LogsDrilldownDefaultColumnsKind()), + } +} + +func NewLogsDrilldownDefaultColumnsClientFromGenerator(generator resource.ClientGenerator) (*LogsDrilldownDefaultColumnsClient, error) { + c, err := generator.ClientFor(LogsDrilldownDefaultColumnsKind()) + if err != nil { + return nil, err + } + return NewLogsDrilldownDefaultColumnsClient(c), nil +} + +func (c *LogsDrilldownDefaultColumnsClient) Get(ctx context.Context, identifier resource.Identifier) (*LogsDrilldownDefaultColumns, error) { + return c.client.Get(ctx, identifier) +} + +func (c *LogsDrilldownDefaultColumnsClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownDefaultColumnsList, error) { + return c.client.List(ctx, namespace, opts) +} + +func (c *LogsDrilldownDefaultColumnsClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*LogsDrilldownDefaultColumnsList, error) { + resp, err := c.client.List(ctx, namespace, resource.ListOptions{ + ResourceVersion: opts.ResourceVersion, + Limit: opts.Limit, + LabelFilters: opts.LabelFilters, + FieldSelectors: opts.FieldSelectors, + }) + if err != nil { + return nil, err + } + for resp.GetContinue() != "" { + page, err := c.client.List(ctx, namespace, resource.ListOptions{ + Continue: resp.GetContinue(), + ResourceVersion: opts.ResourceVersion, + Limit: opts.Limit, + LabelFilters: opts.LabelFilters, + FieldSelectors: opts.FieldSelectors, + }) + if err != nil { + return nil, err + } + resp.SetContinue(page.GetContinue()) + resp.SetResourceVersion(page.GetResourceVersion()) + resp.SetItems(append(resp.GetItems(), page.GetItems()...)) + } + return resp, nil +} + +func (c *LogsDrilldownDefaultColumnsClient) Create(ctx context.Context, obj *LogsDrilldownDefaultColumns, opts resource.CreateOptions) (*LogsDrilldownDefaultColumns, error) { + // Make sure apiVersion and kind are set + obj.APIVersion = GroupVersion.Identifier() + obj.Kind = LogsDrilldownDefaultColumnsKind().Kind() + return c.client.Create(ctx, obj, opts) +} + +func (c *LogsDrilldownDefaultColumnsClient) Update(ctx context.Context, obj *LogsDrilldownDefaultColumns, opts resource.UpdateOptions) (*LogsDrilldownDefaultColumns, error) { + return c.client.Update(ctx, obj, opts) +} + +func (c *LogsDrilldownDefaultColumnsClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*LogsDrilldownDefaultColumns, error) { + return c.client.Patch(ctx, identifier, req, opts) +} + +func (c *LogsDrilldownDefaultColumnsClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus LogsDrilldownDefaultColumnsStatus, opts resource.UpdateOptions) (*LogsDrilldownDefaultColumns, error) { + return c.client.Update(ctx, &LogsDrilldownDefaultColumns{ + TypeMeta: metav1.TypeMeta{ + Kind: LogsDrilldownDefaultColumnsKind().Kind(), + APIVersion: GroupVersion.Identifier(), + }, + ObjectMeta: metav1.ObjectMeta{ + ResourceVersion: opts.ResourceVersion, + Namespace: identifier.Namespace, + Name: identifier.Name, + }, + Status: newStatus, + }, resource.UpdateOptions{ + Subresource: "status", + ResourceVersion: opts.ResourceVersion, + }) +} + +func (c *LogsDrilldownDefaultColumnsClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error { + return c.client.Delete(ctx, identifier, opts) +} diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_codec_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_codec_gen.go new file mode 100644 index 00000000000..12622814e72 --- /dev/null +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_codec_gen.go @@ -0,0 +1,28 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v1beta1 + +import ( + "encoding/json" + "io" + + "github.com/grafana/grafana-app-sdk/resource" +) + +// LogsDrilldownDefaultColumnsJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding +type LogsDrilldownDefaultColumnsJSONCodec struct{} + +// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` +func (*LogsDrilldownDefaultColumnsJSONCodec) Read(reader io.Reader, into resource.Object) error { + return json.NewDecoder(reader).Decode(into) +} + +// Write writes JSON-encoded bytes into `writer` marshaled from `from` +func (*LogsDrilldownDefaultColumnsJSONCodec) Write(writer io.Writer, from resource.Object) error { + return json.NewEncoder(writer).Encode(from) +} + +// Interface compliance checks +var _ resource.Codec = &LogsDrilldownDefaultColumnsJSONCodec{} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_metadata_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_metadata_gen.go similarity index 77% rename from apps/investigations/pkg/apis/investigations/v0alpha1/investigation_metadata_gen.go rename to apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_metadata_gen.go index ffd588fec5e..ee2d44fde2e 100644 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_metadata_gen.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_metadata_gen.go @@ -1,6 +1,6 @@ // Code generated - EDITING IS FUTILE. DO NOT EDIT. -package v0alpha1 +package v1beta1 import ( time "time" @@ -9,7 +9,7 @@ import ( // metadata contains embedded CommonMetadata and can be extended with custom string fields // TODO: use CommonMetadata instead of redefining here; currently needs to be defined here // without external reference as using the CommonMetadata reference breaks thema codegen. -type InvestigationMetadata struct { +type LogsDrilldownDefaultColumnsMetadata struct { UpdateTimestamp time.Time `json:"updateTimestamp"` CreatedBy string `json:"createdBy"` Uid string `json:"uid"` @@ -22,9 +22,9 @@ type InvestigationMetadata struct { Labels map[string]string `json:"labels"` } -// NewInvestigationMetadata creates a new InvestigationMetadata object. -func NewInvestigationMetadata() *InvestigationMetadata { - return &InvestigationMetadata{ +// NewLogsDrilldownDefaultColumnsMetadata creates a new LogsDrilldownDefaultColumnsMetadata object. +func NewLogsDrilldownDefaultColumnsMetadata() *LogsDrilldownDefaultColumnsMetadata { + return &LogsDrilldownDefaultColumnsMetadata{ Finalizers: []string{}, Labels: map[string]string{}, } diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_object_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_object_gen.go similarity index 59% rename from apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_object_gen.go rename to apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_object_gen.go index 67493201f05..6822fbfb4d7 100644 --- a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_object_gen.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_object_gen.go @@ -2,7 +2,7 @@ // Code generated by grafana-app-sdk. DO NOT EDIT. // -package v0alpha1 +package v1beta1 import ( "fmt" @@ -15,22 +15,29 @@ import ( ) // +k8s:openapi-gen=true -type InvestigationIndex struct { +type LogsDrilldownDefaultColumns struct { metav1.TypeMeta `json:",inline" yaml:",inline"` metav1.ObjectMeta `json:"metadata" yaml:"metadata"` - // Spec is the spec of the InvestigationIndex - Spec InvestigationIndexSpec `json:"spec" yaml:"spec"` + // Spec is the spec of the LogsDrilldownDefaultColumns + Spec LogsDrilldownDefaultColumnsSpec `json:"spec" yaml:"spec"` - Status InvestigationIndexStatus `json:"status" yaml:"status"` + Status LogsDrilldownDefaultColumnsStatus `json:"status" yaml:"status"` } -func (o *InvestigationIndex) GetSpec() any { +func NewLogsDrilldownDefaultColumns() *LogsDrilldownDefaultColumns { + return &LogsDrilldownDefaultColumns{ + Spec: *NewLogsDrilldownDefaultColumnsSpec(), + Status: *NewLogsDrilldownDefaultColumnsStatus(), + } +} + +func (o *LogsDrilldownDefaultColumns) GetSpec() any { return o.Spec } -func (o *InvestigationIndex) SetSpec(spec any) error { - cast, ok := spec.(InvestigationIndexSpec) +func (o *LogsDrilldownDefaultColumns) SetSpec(spec any) error { + cast, ok := spec.(LogsDrilldownDefaultColumnsSpec) if !ok { return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) } @@ -38,13 +45,13 @@ func (o *InvestigationIndex) SetSpec(spec any) error { return nil } -func (o *InvestigationIndex) GetSubresources() map[string]any { +func (o *LogsDrilldownDefaultColumns) GetSubresources() map[string]any { return map[string]any{ "status": o.Status, } } -func (o *InvestigationIndex) GetSubresource(name string) (any, bool) { +func (o *LogsDrilldownDefaultColumns) GetSubresource(name string) (any, bool) { switch name { case "status": return o.Status, true @@ -53,12 +60,12 @@ func (o *InvestigationIndex) GetSubresource(name string) (any, bool) { } } -func (o *InvestigationIndex) SetSubresource(name string, value any) error { +func (o *LogsDrilldownDefaultColumns) SetSubresource(name string, value any) error { switch name { case "status": - cast, ok := value.(InvestigationIndexStatus) + cast, ok := value.(LogsDrilldownDefaultColumnsStatus) if !ok { - return fmt.Errorf("cannot set status type %#v, not of type InvestigationIndexStatus", value) + return fmt.Errorf("cannot set status type %#v, not of type LogsDrilldownDefaultColumnsStatus", value) } o.Status = cast return nil @@ -67,7 +74,7 @@ func (o *InvestigationIndex) SetSubresource(name string, value any) error { } } -func (o *InvestigationIndex) GetStaticMetadata() resource.StaticMetadata { +func (o *LogsDrilldownDefaultColumns) GetStaticMetadata() resource.StaticMetadata { gvk := o.GroupVersionKind() return resource.StaticMetadata{ Name: o.ObjectMeta.Name, @@ -78,7 +85,7 @@ func (o *InvestigationIndex) GetStaticMetadata() resource.StaticMetadata { } } -func (o *InvestigationIndex) SetStaticMetadata(metadata resource.StaticMetadata) { +func (o *LogsDrilldownDefaultColumns) SetStaticMetadata(metadata resource.StaticMetadata) { o.Name = metadata.Name o.Namespace = metadata.Namespace o.SetGroupVersionKind(schema.GroupVersionKind{ @@ -88,7 +95,7 @@ func (o *InvestigationIndex) SetStaticMetadata(metadata resource.StaticMetadata) }) } -func (o *InvestigationIndex) GetCommonMetadata() resource.CommonMetadata { +func (o *LogsDrilldownDefaultColumns) GetCommonMetadata() resource.CommonMetadata { dt := o.DeletionTimestamp var deletionTimestamp *time.Time if dt != nil { @@ -120,7 +127,7 @@ func (o *InvestigationIndex) GetCommonMetadata() resource.CommonMetadata { } } -func (o *InvestigationIndex) SetCommonMetadata(metadata resource.CommonMetadata) { +func (o *LogsDrilldownDefaultColumns) SetCommonMetadata(metadata resource.CommonMetadata) { o.UID = types.UID(metadata.UID) o.ResourceVersion = metadata.ResourceVersion o.Generation = metadata.Generation @@ -165,7 +172,7 @@ func (o *InvestigationIndex) SetCommonMetadata(metadata resource.CommonMetadata) } } -func (o *InvestigationIndex) GetCreatedBy() string { +func (o *LogsDrilldownDefaultColumns) GetCreatedBy() string { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -173,7 +180,7 @@ func (o *InvestigationIndex) GetCreatedBy() string { return o.ObjectMeta.Annotations["grafana.com/createdBy"] } -func (o *InvestigationIndex) SetCreatedBy(createdBy string) { +func (o *LogsDrilldownDefaultColumns) SetCreatedBy(createdBy string) { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -181,7 +188,7 @@ func (o *InvestigationIndex) SetCreatedBy(createdBy string) { o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy } -func (o *InvestigationIndex) GetUpdateTimestamp() time.Time { +func (o *LogsDrilldownDefaultColumns) GetUpdateTimestamp() time.Time { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -190,7 +197,7 @@ func (o *InvestigationIndex) GetUpdateTimestamp() time.Time { return parsed } -func (o *InvestigationIndex) SetUpdateTimestamp(updateTimestamp time.Time) { +func (o *LogsDrilldownDefaultColumns) SetUpdateTimestamp(updateTimestamp time.Time) { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -198,7 +205,7 @@ func (o *InvestigationIndex) SetUpdateTimestamp(updateTimestamp time.Time) { o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) } -func (o *InvestigationIndex) GetUpdatedBy() string { +func (o *LogsDrilldownDefaultColumns) GetUpdatedBy() string { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -206,7 +213,7 @@ func (o *InvestigationIndex) GetUpdatedBy() string { return o.ObjectMeta.Annotations["grafana.com/updatedBy"] } -func (o *InvestigationIndex) SetUpdatedBy(updatedBy string) { +func (o *LogsDrilldownDefaultColumns) SetUpdatedBy(updatedBy string) { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -214,21 +221,21 @@ func (o *InvestigationIndex) SetUpdatedBy(updatedBy string) { o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy } -func (o *InvestigationIndex) Copy() resource.Object { +func (o *LogsDrilldownDefaultColumns) Copy() resource.Object { return resource.CopyObject(o) } -func (o *InvestigationIndex) DeepCopyObject() runtime.Object { +func (o *LogsDrilldownDefaultColumns) DeepCopyObject() runtime.Object { return o.Copy() } -func (o *InvestigationIndex) DeepCopy() *InvestigationIndex { - cpy := &InvestigationIndex{} +func (o *LogsDrilldownDefaultColumns) DeepCopy() *LogsDrilldownDefaultColumns { + cpy := &LogsDrilldownDefaultColumns{} o.DeepCopyInto(cpy) return cpy } -func (o *InvestigationIndex) DeepCopyInto(dst *InvestigationIndex) { +func (o *LogsDrilldownDefaultColumns) DeepCopyInto(dst *LogsDrilldownDefaultColumns) { dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion dst.TypeMeta.Kind = o.TypeMeta.Kind o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta) @@ -237,34 +244,34 @@ func (o *InvestigationIndex) DeepCopyInto(dst *InvestigationIndex) { } // Interface compliance compile-time check -var _ resource.Object = &InvestigationIndex{} +var _ resource.Object = &LogsDrilldownDefaultColumns{} // +k8s:openapi-gen=true -type InvestigationIndexList struct { +type LogsDrilldownDefaultColumnsList struct { metav1.TypeMeta `json:",inline" yaml:",inline"` metav1.ListMeta `json:"metadata" yaml:"metadata"` - Items []InvestigationIndex `json:"items" yaml:"items"` + Items []LogsDrilldownDefaultColumns `json:"items" yaml:"items"` } -func (o *InvestigationIndexList) DeepCopyObject() runtime.Object { +func (o *LogsDrilldownDefaultColumnsList) DeepCopyObject() runtime.Object { return o.Copy() } -func (o *InvestigationIndexList) Copy() resource.ListObject { - cpy := &InvestigationIndexList{ +func (o *LogsDrilldownDefaultColumnsList) Copy() resource.ListObject { + cpy := &LogsDrilldownDefaultColumnsList{ TypeMeta: o.TypeMeta, - Items: make([]InvestigationIndex, len(o.Items)), + Items: make([]LogsDrilldownDefaultColumns, len(o.Items)), } o.ListMeta.DeepCopyInto(&cpy.ListMeta) for i := 0; i < len(o.Items); i++ { - if item, ok := o.Items[i].Copy().(*InvestigationIndex); ok { + if item, ok := o.Items[i].Copy().(*LogsDrilldownDefaultColumns); ok { cpy.Items[i] = *item } } return cpy } -func (o *InvestigationIndexList) GetItems() []resource.Object { +func (o *LogsDrilldownDefaultColumnsList) GetItems() []resource.Object { items := make([]resource.Object, len(o.Items)) for i := 0; i < len(o.Items); i++ { items[i] = &o.Items[i] @@ -272,48 +279,48 @@ func (o *InvestigationIndexList) GetItems() []resource.Object { return items } -func (o *InvestigationIndexList) SetItems(items []resource.Object) { - o.Items = make([]InvestigationIndex, len(items)) +func (o *LogsDrilldownDefaultColumnsList) SetItems(items []resource.Object) { + o.Items = make([]LogsDrilldownDefaultColumns, len(items)) for i := 0; i < len(items); i++ { - o.Items[i] = *items[i].(*InvestigationIndex) + o.Items[i] = *items[i].(*LogsDrilldownDefaultColumns) } } -func (o *InvestigationIndexList) DeepCopy() *InvestigationIndexList { - cpy := &InvestigationIndexList{} +func (o *LogsDrilldownDefaultColumnsList) DeepCopy() *LogsDrilldownDefaultColumnsList { + cpy := &LogsDrilldownDefaultColumnsList{} o.DeepCopyInto(cpy) return cpy } -func (o *InvestigationIndexList) DeepCopyInto(dst *InvestigationIndexList) { +func (o *LogsDrilldownDefaultColumnsList) DeepCopyInto(dst *LogsDrilldownDefaultColumnsList) { resource.CopyObjectInto(dst, o) } // Interface compliance compile-time check -var _ resource.ListObject = &InvestigationIndexList{} +var _ resource.ListObject = &LogsDrilldownDefaultColumnsList{} // Copy methods for all subresource types // DeepCopy creates a full deep copy of Spec -func (s *InvestigationIndexSpec) DeepCopy() *InvestigationIndexSpec { - cpy := &InvestigationIndexSpec{} +func (s *LogsDrilldownDefaultColumnsSpec) DeepCopy() *LogsDrilldownDefaultColumnsSpec { + cpy := &LogsDrilldownDefaultColumnsSpec{} s.DeepCopyInto(cpy) return cpy } // DeepCopyInto deep copies Spec into another Spec object -func (s *InvestigationIndexSpec) DeepCopyInto(dst *InvestigationIndexSpec) { +func (s *LogsDrilldownDefaultColumnsSpec) DeepCopyInto(dst *LogsDrilldownDefaultColumnsSpec) { resource.CopyObjectInto(dst, s) } -// DeepCopy creates a full deep copy of InvestigationIndexStatus -func (s *InvestigationIndexStatus) DeepCopy() *InvestigationIndexStatus { - cpy := &InvestigationIndexStatus{} +// DeepCopy creates a full deep copy of LogsDrilldownDefaultColumnsStatus +func (s *LogsDrilldownDefaultColumnsStatus) DeepCopy() *LogsDrilldownDefaultColumnsStatus { + cpy := &LogsDrilldownDefaultColumnsStatus{} s.DeepCopyInto(cpy) return cpy } -// DeepCopyInto deep copies InvestigationIndexStatus into another InvestigationIndexStatus object -func (s *InvestigationIndexStatus) DeepCopyInto(dst *InvestigationIndexStatus) { +// DeepCopyInto deep copies LogsDrilldownDefaultColumnsStatus into another LogsDrilldownDefaultColumnsStatus object +func (s *LogsDrilldownDefaultColumnsStatus) DeepCopyInto(dst *LogsDrilldownDefaultColumnsStatus) { resource.CopyObjectInto(dst, s) } diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_schema_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_schema_gen.go new file mode 100644 index 00000000000..49d234f47a5 --- /dev/null +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_schema_gen.go @@ -0,0 +1,34 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v1beta1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" +) + +// schema is unexported to prevent accidental overwrites +var ( + schemaLogsDrilldownDefaultColumns = resource.NewSimpleSchema("logsdrilldown.grafana.app", "v1beta1", NewLogsDrilldownDefaultColumns(), &LogsDrilldownDefaultColumnsList{}, resource.WithKind("LogsDrilldownDefaultColumns"), + resource.WithPlural("logsdrilldowndefaultcolumns"), resource.WithScope(resource.NamespacedScope)) + kindLogsDrilldownDefaultColumns = resource.Kind{ + Schema: schemaLogsDrilldownDefaultColumns, + Codecs: map[resource.KindEncoding]resource.Codec{ + resource.KindEncodingJSON: &LogsDrilldownDefaultColumnsJSONCodec{}, + }, + } +) + +// Kind returns a resource.Kind for this Schema with a JSON codec +func LogsDrilldownDefaultColumnsKind() resource.Kind { + return kindLogsDrilldownDefaultColumns +} + +// Schema returns a resource.SimpleSchema representation of LogsDrilldownDefaultColumns +func LogsDrilldownDefaultColumnsSchema() *resource.SimpleSchema { + return schemaLogsDrilldownDefaultColumns +} + +// Interface compliance checks +var _ resource.Schema = kindLogsDrilldownDefaultColumns diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_spec_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_spec_gen.go new file mode 100644 index 00000000000..6163f66c52c --- /dev/null +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_spec_gen.go @@ -0,0 +1,43 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v1beta1 + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords []LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord struct { + Columns []string `json:"columns"` + Labels LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels `json:"labels"` +} + +// NewLogsDrilldownDefaultColumnsLogsDefaultColumnsRecord creates a new LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord object. +func NewLogsDrilldownDefaultColumnsLogsDefaultColumnsRecord() *LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord { + return &LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord{ + Columns: []string{}, + } +} + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels []LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel struct { + Key string `json:"key"` + Value string `json:"value"` +} + +// NewLogsDrilldownDefaultColumnsLogsDefaultColumnsLabel creates a new LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel object. +func NewLogsDrilldownDefaultColumnsLogsDefaultColumnsLabel() *LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel { + return &LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel{} +} + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsSpec struct { + Records LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords `json:"records"` +} + +// NewLogsDrilldownDefaultColumnsSpec creates a new LogsDrilldownDefaultColumnsSpec object. +func NewLogsDrilldownDefaultColumnsSpec() *LogsDrilldownDefaultColumnsSpec { + return &LogsDrilldownDefaultColumnsSpec{} +} diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_status_gen.go b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_status_gen.go new file mode 100644 index 00000000000..e109592eb09 --- /dev/null +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1/logsdrilldowndefaultcolumns_status_gen.go @@ -0,0 +1,44 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v1beta1 + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsstatusOperatorState struct { + // lastEvaluation is the ResourceVersion last evaluated + LastEvaluation string `json:"lastEvaluation"` + // state describes the state of the lastEvaluation. + // It is limited to three possible states for machine evaluation. + State LogsDrilldownDefaultColumnsStatusOperatorStateState `json:"state"` + // descriptiveState is an optional more descriptive state field which has no requirements on format + DescriptiveState *string `json:"descriptiveState,omitempty"` + // details contains any extra information that is operator-specific + Details map[string]interface{} `json:"details,omitempty"` +} + +// NewLogsDrilldownDefaultColumnsstatusOperatorState creates a new LogsDrilldownDefaultColumnsstatusOperatorState object. +func NewLogsDrilldownDefaultColumnsstatusOperatorState() *LogsDrilldownDefaultColumnsstatusOperatorState { + return &LogsDrilldownDefaultColumnsstatusOperatorState{} +} + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsStatus struct { + // operatorStates is a map of operator ID to operator state evaluations. + // Any operator which consumes this kind SHOULD add its state evaluation information to this field. + OperatorStates map[string]LogsDrilldownDefaultColumnsstatusOperatorState `json:"operatorStates,omitempty"` + // additionalFields is reserved for future use + AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` +} + +// NewLogsDrilldownDefaultColumnsStatus creates a new LogsDrilldownDefaultColumnsStatus object. +func NewLogsDrilldownDefaultColumnsStatus() *LogsDrilldownDefaultColumnsStatus { + return &LogsDrilldownDefaultColumnsStatus{} +} + +// +k8s:openapi-gen=true +type LogsDrilldownDefaultColumnsStatusOperatorStateState string + +const ( + LogsDrilldownDefaultColumnsStatusOperatorStateStateSuccess LogsDrilldownDefaultColumnsStatusOperatorStateState = "success" + LogsDrilldownDefaultColumnsStatusOperatorStateStateInProgress LogsDrilldownDefaultColumnsStatusOperatorStateState = "in_progress" + LogsDrilldownDefaultColumnsStatusOperatorStateStateFailed LogsDrilldownDefaultColumnsStatusOperatorStateState = "failed" +) diff --git a/apps/logsdrilldown/pkg/apis/logsdrilldown_manifest.go b/apps/logsdrilldown/pkg/apis/logsdrilldown_manifest.go index ef0d5801511..a242d11b2bf 100644 --- a/apps/logsdrilldown/pkg/apis/logsdrilldown_manifest.go +++ b/apps/logsdrilldown/pkg/apis/logsdrilldown_manifest.go @@ -17,21 +17,25 @@ import ( "k8s.io/kube-openapi/pkg/validation/spec" v1alpha1 "github.com/grafana/grafana/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1" + v1beta1 "github.com/grafana/grafana/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1" ) var ( - rawSchemaLogsDrilldownv1alpha1 = []byte(`{"LogsDrilldown":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) - versionSchemaLogsDrilldownv1alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaLogsDrilldownv1alpha1, &versionSchemaLogsDrilldownv1alpha1) - rawSchemaLogsDrilldownDefaultsv1alpha1 = []byte(`{"LogsDrilldownDefaults":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) - versionSchemaLogsDrilldownDefaultsv1alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaLogsDrilldownDefaultsv1alpha1, &versionSchemaLogsDrilldownDefaultsv1alpha1) + rawSchemaLogsDrilldownv1alpha1 = []byte(`{"LogsDrilldown":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) + versionSchemaLogsDrilldownv1alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaLogsDrilldownv1alpha1, &versionSchemaLogsDrilldownv1alpha1) + rawSchemaLogsDrilldownDefaultsv1alpha1 = []byte(`{"LogsDrilldownDefaults":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"defaultFields":{"items":{"type":"string"},"type":"array"},"interceptDismissed":{"type":"boolean"},"prettifyJSON":{"type":"boolean"},"wrapLogMessage":{"type":"boolean"}},"required":["defaultFields","prettifyJSON","wrapLogMessage","interceptDismissed"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) + versionSchemaLogsDrilldownDefaultsv1alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaLogsDrilldownDefaultsv1alpha1, &versionSchemaLogsDrilldownDefaultsv1alpha1) + rawSchemaLogsDrilldownDefaultColumnsv1beta1 = []byte(`{"LogsDefaultColumnsLabel":{"additionalProperties":false,"properties":{"key":{"type":"string"},"value":{"type":"string"}},"required":["key","value"],"type":"object"},"LogsDefaultColumnsLabels":{"items":{"$ref":"#/components/schemas/LogsDefaultColumnsLabel"},"type":"array"},"LogsDefaultColumnsRecord":{"additionalProperties":false,"properties":{"columns":{"items":{"type":"string"},"type":"array"},"labels":{"$ref":"#/components/schemas/LogsDefaultColumnsLabels"}},"required":["columns","labels"],"type":"object"},"LogsDefaultColumnsRecords":{"items":{"$ref":"#/components/schemas/LogsDefaultColumnsRecord"},"type":"array"},"LogsDrilldownDefaultColumns":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"spec":{"additionalProperties":false,"properties":{"records":{"$ref":"#/components/schemas/LogsDefaultColumnsRecords"}},"required":["records"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) + versionSchemaLogsDrilldownDefaultColumnsv1beta1 app.VersionSchema + _ = json.Unmarshal(rawSchemaLogsDrilldownDefaultColumnsv1beta1, &versionSchemaLogsDrilldownDefaultColumnsv1beta1) ) var appManifestData = app.ManifestData{ AppName: "logsdrilldown", Group: "logsdrilldown.grafana.app", - PreferredVersion: "v1alpha1", + PreferredVersion: "v1beta1", Versions: []app.ManifestVersion{ { Name: "v1alpha1", @@ -59,6 +63,25 @@ var appManifestData = app.ManifestData{ Schemas: map[string]spec.Schema{}, }, }, + + { + Name: "v1beta1", + Served: true, + Kinds: []app.ManifestVersionKind{ + { + Kind: "LogsDrilldownDefaultColumns", + Plural: "LogsDrilldownDefaultColumns", + Scope: "Namespaced", + Conversion: false, + Schema: &versionSchemaLogsDrilldownDefaultColumnsv1beta1, + }, + }, + Routes: app.ManifestVersionRoutes{ + Namespaced: map[string]spec3.PathProps{}, + Cluster: map[string]spec3.PathProps{}, + Schemas: map[string]spec.Schema{}, + }, + }, }, } @@ -71,8 +94,9 @@ func RemoteManifest() app.Manifest { } var kindVersionToGoType = map[string]resource.Kind{ - "LogsDrilldown/v1alpha1": v1alpha1.LogsDrilldownKind(), - "LogsDrilldownDefaults/v1alpha1": v1alpha1.LogsDrilldownDefaultsKind(), + "LogsDrilldown/v1alpha1": v1alpha1.LogsDrilldownKind(), + "LogsDrilldownDefaults/v1alpha1": v1alpha1.LogsDrilldownDefaultsKind(), + "LogsDrilldownDefaultColumns/v1beta1": v1beta1.LogsDrilldownDefaultColumnsKind(), } // ManifestGoTypeAssociator returns the associated resource.Kind instance for a given Kind and Version, if one exists. diff --git a/apps/logsdrilldown/pkg/app/app.go b/apps/logsdrilldown/pkg/app/app.go index 7fda1ecb99f..1e3e37851e2 100644 --- a/apps/logsdrilldown/pkg/app/app.go +++ b/apps/logsdrilldown/pkg/app/app.go @@ -11,6 +11,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" logsdrilldownv1alpha1 "github.com/grafana/grafana/apps/logsdrilldown/pkg/apis/logsdrilldown/v1alpha1" + logsdrilldownv1beta1 "github.com/grafana/grafana/apps/logsdrilldown/pkg/apis/logsdrilldown/v1beta1" ) func New(cfg app.Config) (app.App, error) { @@ -31,6 +32,9 @@ func New(cfg app.Config) (app.App, error) { { Kind: logsdrilldownv1alpha1.LogsDrilldownDefaultsKind(), }, + { + Kind: logsdrilldownv1beta1.LogsDrilldownDefaultColumnsKind(), + }, }, } diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/investigationindex_object_gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/logsdrilldowndefaultcolumns_object_gen.ts similarity index 95% rename from apps/investigations/plugin/src/generated/investigationindex/v0alpha1/investigationindex_object_gen.ts rename to apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/logsdrilldowndefaultcolumns_object_gen.ts index 7d88430d451..f7ba7b0f223 100644 --- a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/investigationindex_object_gen.ts +++ b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/logsdrilldowndefaultcolumns_object_gen.ts @@ -40,7 +40,7 @@ export interface ManagedFieldsEntry { subresource?: string; } -export interface InvestigationIndex { +export interface LogsDrilldownDefaultColumns { kind: string; apiVersion: string; metadata: Metadata; diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.metadata.gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/types.metadata.gen.ts similarity index 100% rename from apps/investigations/plugin/src/generated/investigation/v0alpha1/types.metadata.gen.ts rename to apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/types.metadata.gen.ts diff --git a/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/types.spec.gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/types.spec.gen.ts new file mode 100644 index 00000000000..fde99894776 --- /dev/null +++ b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/types.spec.gen.ts @@ -0,0 +1,38 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export type LogsDefaultColumnsRecords = LogsDefaultColumnsRecord[]; + +export const defaultLogsDefaultColumnsRecords = (): LogsDefaultColumnsRecords => ([]); + +export interface LogsDefaultColumnsRecord { + columns: string[]; + labels: LogsDefaultColumnsLabels; +} + +export const defaultLogsDefaultColumnsRecord = (): LogsDefaultColumnsRecord => ({ + columns: [], + labels: defaultLogsDefaultColumnsLabels(), +}); + +export type LogsDefaultColumnsLabels = LogsDefaultColumnsLabel[]; + +export const defaultLogsDefaultColumnsLabels = (): LogsDefaultColumnsLabels => ([]); + +export interface LogsDefaultColumnsLabel { + key: string; + value: string; +} + +export const defaultLogsDefaultColumnsLabel = (): LogsDefaultColumnsLabel => ({ + key: "", + value: "", +}); + +export interface Spec { + records: LogsDefaultColumnsRecords; +} + +export const defaultSpec = (): Spec => ({ + records: defaultLogsDefaultColumnsRecords(), +}); + diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.status.gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/types.status.gen.ts similarity index 100% rename from apps/investigations/plugin/src/generated/investigation/v0alpha1/types.status.gen.ts rename to apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1alpha1/types.status.gen.ts diff --git a/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/logsdrilldowndefaultcolumns_object_gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/logsdrilldowndefaultcolumns_object_gen.ts new file mode 100644 index 00000000000..f7ba7b0f223 --- /dev/null +++ b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/logsdrilldowndefaultcolumns_object_gen.ts @@ -0,0 +1,49 @@ +/* + * This file was generated by grafana-app-sdk. DO NOT EDIT. + */ +import { Spec } from './types.spec.gen'; +import { Status } from './types.status.gen'; + +export interface Metadata { + name: string; + namespace: string; + generateName?: string; + selfLink?: string; + uid?: string; + resourceVersion?: string; + generation?: number; + creationTimestamp?: string; + deletionTimestamp?: string; + deletionGracePeriodSeconds?: number; + labels?: Record; + annotations?: Record; + ownerReferences?: OwnerReference[]; + finalizers?: string[]; + managedFields?: ManagedFieldsEntry[]; +} + +export interface OwnerReference { + apiVersion: string; + kind: string; + name: string; + uid: string; + controller?: boolean; + blockOwnerDeletion?: boolean; +} + +export interface ManagedFieldsEntry { + manager?: string; + operation?: string; + apiVersion?: string; + time?: string; + fieldsType?: string; + subresource?: string; +} + +export interface LogsDrilldownDefaultColumns { + kind: string; + apiVersion: string; + metadata: Metadata; + spec: Spec; + status: Status; +} diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.metadata.gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/types.metadata.gen.ts similarity index 100% rename from apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.metadata.gen.ts rename to apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/types.metadata.gen.ts diff --git a/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/types.spec.gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/types.spec.gen.ts new file mode 100644 index 00000000000..fde99894776 --- /dev/null +++ b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/types.spec.gen.ts @@ -0,0 +1,38 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export type LogsDefaultColumnsRecords = LogsDefaultColumnsRecord[]; + +export const defaultLogsDefaultColumnsRecords = (): LogsDefaultColumnsRecords => ([]); + +export interface LogsDefaultColumnsRecord { + columns: string[]; + labels: LogsDefaultColumnsLabels; +} + +export const defaultLogsDefaultColumnsRecord = (): LogsDefaultColumnsRecord => ({ + columns: [], + labels: defaultLogsDefaultColumnsLabels(), +}); + +export type LogsDefaultColumnsLabels = LogsDefaultColumnsLabel[]; + +export const defaultLogsDefaultColumnsLabels = (): LogsDefaultColumnsLabels => ([]); + +export interface LogsDefaultColumnsLabel { + key: string; + value: string; +} + +export const defaultLogsDefaultColumnsLabel = (): LogsDefaultColumnsLabel => ({ + key: "", + value: "", +}); + +export interface Spec { + records: LogsDefaultColumnsRecords; +} + +export const defaultSpec = (): Spec => ({ + records: defaultLogsDefaultColumnsRecords(), +}); + diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.status.gen.ts b/apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/types.status.gen.ts similarity index 100% rename from apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.status.gen.ts rename to apps/logsdrilldown/plugin/src/generated/logsdrilldowndefaultcolumns/v1beta1/types.status.gen.ts diff --git a/apps/playlist/go.mod b/apps/playlist/go.mod index ae38e3d0cd3..dd749f9fede 100644 --- a/apps/playlist/go.mod +++ b/apps/playlist/go.mod @@ -3,16 +3,16 @@ module github.com/grafana/grafana/apps/playlist go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - k8s.io/apimachinery v0.34.2 - k8s.io/client-go v0.34.2 + github.com/grafana/grafana-app-sdk v0.48.7 + k8s.io/apimachinery v0.34.3 + k8s.io/client-go v0.34.3 k8s.io/klog/v2 v2.130.1 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -22,23 +22,33 @@ require ( github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.48.3 // indirect + github.com/grafana/grafana-app-sdk/logging v0.48.7 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -51,41 +61,41 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/playlist/go.sum b/apps/playlist/go.sum index 3df8e8b5ebe..e5233ba82c9 100644 --- a/apps/playlist/go.sum +++ b/apps/playlist/go.sum @@ -1,7 +1,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -23,14 +23,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -39,8 +65,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -48,10 +74,10 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -73,8 +99,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -95,8 +121,6 @@ github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -104,10 +128,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -122,30 +146,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -163,34 +187,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -199,39 +223,39 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/plugins/README.md b/apps/plugins/README.md new file mode 100644 index 00000000000..7f91dd6ea12 --- /dev/null +++ b/apps/plugins/README.md @@ -0,0 +1,20 @@ +# Plugins App + +API documentation is available at http://localhost:3000/swagger?api=plugins.grafana.app-v0alpha1 + +## Codegen + +- Go: `make generate` +- Frontend: Follow instructions in this [README](../..//packages/grafana-api-clients/README.md) + +## Plugin sync + +The plugin sync pushes the plugins loaded from disk to the plugins API. + +To enable, add these feature toggles in your `custom.ini`: + +```ini +[feature_toggles] +pluginInstallAPISync = true +pluginStoreServiceLoading = true +``` diff --git a/apps/plugins/go.mod b/apps/plugins/go.mod index 669c7c46844..e4866731967 100644 --- a/apps/plugins/go.mod +++ b/apps/plugins/go.mod @@ -8,45 +8,56 @@ replace github.com/grafana/grafana/pkg/apimachinery => ../../pkg/apimachinery replace github.com/grafana/grafana/pkg/apiserver => ../../pkg/apiserver +replace github.com/grafana/grafana/pkg/plugins => ../../pkg/plugins + +replace github.com/grafana/grafana/pkg/semconv => ../../pkg/semconv + require ( github.com/emicklei/go-restful/v3 v3.13.0 - github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 github.com/grafana/grafana v0.0.0-00010101000000-000000000000 - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0 + github.com/grafana/grafana/pkg/plugins v0.0.0 github.com/stretchr/testify v1.11.1 - k8s.io/apimachinery v0.34.2 - k8s.io/apiserver v0.34.2 - k8s.io/client-go v0.34.2 + k8s.io/apimachinery v0.34.3 + k8s.io/apiserver v0.34.3 + k8s.io/client-go v0.34.3 k8s.io/klog/v2 v2.130.1 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( - cel.dev/expr v0.24.0 // indirect + cel.dev/expr v0.25.1 // indirect + github.com/Machiel/slugify v1.0.1 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect + github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/apache/arrow-go/v18 v18.4.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go-v2 v1.39.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.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.8 // 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.8 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 // indirect - github.com/aws/smithy-go v1.23.1 // indirect + github.com/aws/aws-sdk-go-v2 v1.40.0 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // 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/presigned-url v1.13.13 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // indirect + github.com/aws/smithy-go v1.23.2 // indirect + github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bluele/gcache v0.0.2 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/bwmarrin/snowflake v0.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect + github.com/cloudflare/circl v1.6.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/diegoholiveira/jsonlogic/v3 v3.7.4 // indirect github.com/evanphx/json-patch v5.9.11+incompatible // indirect github.com/fatih/color v1.18.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -58,10 +69,20 @@ require ( github.com/go-logfmt/logfmt v0.6.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gobwas/glob v0.2.3 // indirect @@ -73,20 +94,22 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/cel-go v0.26.1 // indirect github.com/google/flatbuffers v25.2.10+incompatible // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba // indirect + github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f // indirect github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect + github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect - github.com/grafana/grafana-aws-sdk v1.3.0 // indirect + github.com/grafana/grafana-aws-sdk v1.4.2 // indirect github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 // indirect github.com/grafana/grafana-plugin-sdk-go v0.284.0 // indirect github.com/grafana/grafana/pkg/apiserver v0.0.0 // indirect + github.com/grafana/grafana/pkg/semconv v0.0.0 // indirect github.com/grafana/otel-profiling-go v0.5.1 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect - github.com/grafana/sqlds/v4 v4.2.7 // indirect + github.com/grafana/sqlds/v5 v5.0.3 // 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-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect @@ -113,7 +136,7 @@ require ( github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -132,11 +155,15 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect + github.com/nikunjy/rules v1.5.0 // indirect github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/open-feature/go-sdk v1.16.0 // indirect + github.com/open-feature/go-sdk-contrib/providers/go-feature-flag v0.2.6 // indirect + github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.6 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pierrec/lz4/v4 v4.1.22 // indirect @@ -145,72 +172,75 @@ require ( github.com/prometheus/alertmanager v0.28.2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect + github.com/prometheus/common v0.67.4 // indirect github.com/prometheus/exporter-toolkit v0.14.0 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect - github.com/spf13/cobra v1.10.1 // indirect + github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/stoewer/go-strcase v1.3.1 // indirect github.com/stretchr/objx v0.5.2 // indirect + github.com/thomaspoignant/go-feature-flag v1.42.0 // indirect github.com/tjhop/slog-gokit v0.1.5 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.etcd.io/etcd/api/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/v3 v3.6.4 // indirect + go.etcd.io/etcd/api/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/v3 v3.6.6 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // indirect go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // indirect - golang.org/x/mod v0.30.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/component-base v0.34.2 // indirect - k8s.io/kms v0.34.2 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/component-base v0.34.3 // indirect + k8s.io/kms v0.34.3 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/plugins/go.sum b/apps/plugins/go.sum index 1d7387b28b3..29738a48cca 100644 --- a/apps/plugins/go.sum +++ b/apps/plugins/go.sum @@ -1,12 +1,18 @@ -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Machiel/slugify v1.0.1 h1:EfWSlRWstMadsgzmiV7d0yVd2IFlagWH68Q+DcYCm4E= +github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw= +github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -22,30 +28,36 @@ github.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc= github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/aws/aws-sdk-go-v2 v1.39.1 h1:fWZhGAwVRK/fAN2tmt7ilH4PPAE11rDj7HytrmbZ2FE= -github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= -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.14/go.mod h1:12x4Uw/vijC11XkctTjy92TNCQ+UnNJkT7fzX0Yd93E= -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.8/go.mod h1:KcGkXFVU8U28qS4KvLEcPxytPZPBcRawaH2Pf/0jptE= -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.8/go.mod h1:JnA+hPWeYAVbDssp83tv+ysAG8lTfLVXvSsyKg/7xNA= -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.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= -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.8/go.mod h1:Fw+MyTwlwjFsSTE31mH211Np+CUslml8mzc0AFEG09s= -github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 h1:+LVB0xBqEgjQoqr9bGZbRzvg212B0f17JdflleJRNR4= -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.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= -github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc= +github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= +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.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= +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.14/go.mod h1:VymhrMJUWs69D8u0/lZ7jSB6WgaG/NqHi3gX0aYf6U0= +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.14/go.mod h1:1ipeGBMAxZ0xcTm6y6paC2C/J6f6OO7LBODV9afuAyM= +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.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= +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.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= +github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= +github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df h1:GSoSVRLoBaFpOOds6QyY1L8AX7uoY+Ln3BHc22W40X0= +github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df/go.mod h1:hiVxq5OP2bUGBRNS3Z/bt/reCLFNbdcST6gISi1fiOM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw= +github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= @@ -60,15 +72,19 @@ github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wX github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= +github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/diegoholiveira/jsonlogic/v3 v3.7.4 h1:92HSmB9bwM/o0ZvrCpcvTP2EsPXSkKtAniIr2W/dcIM= +github.com/diegoholiveira/jsonlogic/v3 v3.7.4/go.mod h1:OYRb6FSTVmMM+MNQ7ElmMsczyNSepw+OU4Z8emDSi4w= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= @@ -106,14 +122,40 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -127,7 +169,6 @@ github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -157,8 +198,8 @@ github.com/google/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ= github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -174,8 +215,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/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/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba h1:psKWNETD5nGxmFAlqnWsXoRyUwSa2GHNEMSEDKGKfQ4= -github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f h1:Br4SaUL3dnVopKKNhDavCLgehw60jdtl/sIxdfzmVts= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f/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/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg= github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGrHj3GdFbvsMzUT7eusgii9PKf9L1ZaXDDbY= @@ -184,12 +225,12 @@ github.com/grafana/dataplane/sdata v0.0.9 h1:AGL1LZnCUG4MnQtnWpBPbQ8ZpptaZs14w6k github.com/grafana/dataplane/sdata v0.0.9/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= 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/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= -github.com/grafana/grafana-aws-sdk v1.3.0 h1:/bfJzP93rCel1GbWoRSq0oUo424MZXt8jAp2BK9w8tM= -github.com/grafana/grafana-aws-sdk v1.3.0/go.mod h1:VGycF0JkCGKND2O5je1ucOqPJ0ZNhZYzV3c2bNBAaGk= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= +github.com/grafana/grafana-aws-sdk v1.4.2 h1:GrUEoLbs46r8rG/GZL4L2b63Bo+rkIYKdtCT7kT5KkM= +github.com/grafana/grafana-aws-sdk v1.4.2/go.mod h1:1qnZdYs6gQzxxF0dDodaE7Rn9fiMzuhwvtaAZ7ySnhY= 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-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad0a5JpEL4mH9ry7Ws= @@ -200,8 +241,8 @@ github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604 github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU= github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= -github.com/grafana/sqlds/v4 v4.2.7 h1:sFQhsS7DBakNMdxa++yOfJ9BVvkZwFJ0B95o57K0/XA= -github.com/grafana/sqlds/v4 v4.2.7/go.mod h1:BQRjUG8rOqrBI4NAaeoWrIMuoNgfi8bdhCJ+5cgEfLU= +github.com/grafana/sqlds/v5 v5.0.3 h1:+yUMUxfa0WANQsmS9xtTFSRX1Q55Iv1B9EjlrW4VlBU= +github.com/grafana/sqlds/v5 v5.0.3/go.mod h1:GKeTTiC+GeR1X0z3f0Iee+hZnNgN62uQpj5XVMx5Uew= 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/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns= @@ -286,8 +327,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM= github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -341,6 +382,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nikunjy/rules v1.5.0 h1:KJDSLOsFhwt7kcXUyZqwkgrQg5YoUwj+TVu6ItCQShw= +github.com/nikunjy/rules v1.5.0/go.mod h1:TlZtZdBChrkqi8Lr2AXocme8Z7EsbxtFdDoKeI6neBQ= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= @@ -355,6 +398,12 @@ github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/open-feature/go-sdk v1.16.0 h1:5NCHYv5slvNBIZhYXAzAufo0OI59OACZ5tczVqSE+Tg= +github.com/open-feature/go-sdk v1.16.0/go.mod h1:EIF40QcoYT1VbQkMPy2ZJH4kvZeY+qGUXAorzSWgKSo= +github.com/open-feature/go-sdk-contrib/providers/go-feature-flag v0.2.6 h1:megzzlQGjsRVWDX8oJnLaa5eEcsAHekiL4Uvl3jSAcY= +github.com/open-feature/go-sdk-contrib/providers/go-feature-flag v0.2.6/go.mod h1:K1gDKvt76CGFLSUMHUydd5ba2V5Cv69gQZsdbnXhAm8= +github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.6 h1:WinefYxeVx5rV0uQmuWbxQf8iACu/JiRubo5w0saToc= +github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.6/go.mod h1:Dwcaoma6lZVqYwyfVlY7eB6RXbG+Ju3b9cnpTlUN+Hc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= @@ -388,8 +437,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg= github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -398,8 +447,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -417,8 +466,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -440,6 +489,10 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/thejerf/slogassert v0.3.4 h1:VoTsXixRbXMrRSSxDjYTiEDCM4VWbsYPW5rB/hX24kM= +github.com/thejerf/slogassert v0.3.4/go.mod h1:0zn9ISLVKo1aPMTqcGfG1o6dWwt+Rk574GlUxHD4rs8= +github.com/thomaspoignant/go-feature-flag v1.42.0 h1:C7embmOTzaLyRki+OoU2RvtVjJE9IrvgBA2C1mRN1lc= +github.com/thomaspoignant/go-feature-flag v1.42.0/go.mod h1:y0QiWH7chHWhGATb/+XqwAwErORmPSH2MUsQlCmmWlM= github.com/tjhop/slog-gokit v0.1.5 h1:ayloIUi5EK2QYB8eY4DOPO95/mRtMW42lUkp3quJohc= github.com/tjhop/slog-gokit v0.1.5/go.mod h1:yA48zAHvV+Sg4z4VRyeFyFUNNXd3JY5Zg84u3USICq0= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= @@ -447,8 +500,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk= @@ -461,12 +514,12 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/api/v3 v3.6.6 h1:mcaMp3+7JawWv69p6QShYWS8cIWUOl32bFLb6qf8pOQ= +go.etcd.io/etcd/api/v3 v3.6.6/go.mod h1:f/om26iXl2wSkcTA1zGQv8reJRSLVdoEBsi4JdfMrx4= +go.etcd.io/etcd/client/pkg/v3 v3.6.6 h1:uoqgzSOv2H9KlIF5O1Lsd8sW+eMLuV6wzE3q5GJGQNs= +go.etcd.io/etcd/client/pkg/v3 v3.6.6/go.mod h1:YngfUVmvsvOJ2rRgStIyHsKtOt9SZI2aBJrZiWJhCbI= +go.etcd.io/etcd/client/v3 v3.6.6 h1:G5z1wMf5B9SNexoxOHUGBaULurOZPIgGPsW6CN492ec= +go.etcd.io/etcd/client/v3 v3.6.6/go.mod h1:36Qv6baQ07znPR3+n7t+Rk5VHEzVYPvFfGmfF4wBHV8= go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA= go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE= go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU= @@ -475,40 +528,44 @@ go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ= go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 h1:2pn7OzMewmYRiNtv1doZnLo3gONcnMHlFnmOR8Vgt+8= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0/go.mod h1:rjbQTDEPQymPE0YnRQp9/NuPwwtL0sesz/fnqRW/v84= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 h1:nXGeLvT1QtCAhkASkP/ksjkTKZALIaQBIW+JSIw1KIc= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0/go.mod h1:oMvOXk78ZR3KEuPMBgp/ThAMDy9ku/eyUVztr+3G6Wo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 h1:oPW/SRFyHgIgxrvNhSBzqvZER2N5kRlci3/rGTOuyWo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0/go.mod h1:B9Oka5QVD0bnmZNO6gBbBta6nohD/1Z+f9waH2oXyBs= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= @@ -521,15 +578,15 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -542,12 +599,12 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -555,8 +612,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -578,17 +635,17 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -596,8 +653,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -611,10 +668,10 @@ gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= @@ -625,15 +682,15 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= @@ -651,30 +708,30 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= -k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ= -k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/component-base v0.34.3 h1:zsEgw6ELqK0XncCQomgO9DpUIzlrYuZYA0Cgo+JWpVk= +k8s.io/component-base v0.34.3/go.mod h1:5iIlD8wPfWE/xSHTRfbjuvUul2WZbI2nOUK65XL0E/c= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.34.2 h1:91rj4MDZLyIT9KxG8J5/CcMH666Z88CF/xJQeuPfJc8= -k8s.io/kms v0.34.2/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kms v0.34.3 h1:QzBOD0sk1bGQVMcZQAHGjtbP1iKZJUyhC6D0I+BTxIE= +k8s.io/kms v0.34.3/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/plugins/kinds/manifest.cue b/apps/plugins/kinds/manifest.cue index f9a08562cb0..f624dc117bc 100644 --- a/apps/plugins/kinds/manifest.cue +++ b/apps/plugins/kinds/manifest.cue @@ -16,6 +16,6 @@ v0alpha1Version: { } kinds: [ pluginV0Alpha1, - pluginMetaV0Alpha1, + metaV0Alpha1, ] } diff --git a/apps/plugins/kinds/pluginmeta.cue b/apps/plugins/kinds/meta.cue similarity index 84% rename from apps/plugins/kinds/pluginmeta.cue rename to apps/plugins/kinds/meta.cue index 03b1ff10ff2..01dc45adf77 100644 --- a/apps/plugins/kinds/pluginmeta.cue +++ b/apps/plugins/kinds/meta.cue @@ -1,12 +1,29 @@ package plugins -pluginMetaV0Alpha1: { - kind: "PluginMeta" - plural: "pluginsmeta" +metaV0Alpha1: { + kind: "Meta" scope: "Namespaced" schema: { spec: { - pluginJSON: #JSONData, + pluginJson: #JSONData + class: "core" | "external" + module?: { + path: string + hash?: string + loadingStrategy?: "fetch" | "script" + } + baseURL?: string + signature?: { + status: "internal" | "valid" | "invalid" | "modified" | "unsigned" + type?: "grafana" | "commercial" | "community" | "private" | "private-glob" + org?: string + } + angular?: { + detected: bool + } + translations?: [string]: string + // +listType=atomic + children?: [...string] } } } @@ -120,7 +137,7 @@ pluginMetaV0Alpha1: { type?: "dashboard" | "page" | "panel" | "datasource" name?: string component?: string - role?: "Admin" | "Editor" | "Viewer" + role?: "Admin" | "Editor" | "Viewer" | "None" action?: string path?: string addToNav?: bool @@ -200,6 +217,13 @@ pluginMetaV0Alpha1: { title: string description?: string }] + // +listType=atomic + addedFunctions?: [...{ + // +listType=set + targets: [...string] + title: string + description?: string + }] // +listType=set // +listMapKey=id exposedComponents?: [...{ diff --git a/apps/plugins/kinds/plugin.cue b/apps/plugins/kinds/plugin.cue index dc16a3f6de4..854448a5b72 100644 --- a/apps/plugins/kinds/plugin.cue +++ b/apps/plugins/kinds/plugin.cue @@ -9,7 +9,6 @@ pluginV0Alpha1: { id: string version: string url?: string - class: "core" | "external" } } } diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_client_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_client_gen.go similarity index 50% rename from apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_client_gen.go rename to apps/plugins/pkg/apis/plugins/v0alpha1/meta_client_gen.go index e7788e27a33..4acc2b635e8 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_client_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_client_gen.go @@ -7,33 +7,33 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -type PluginMetaClient struct { - client *resource.TypedClient[*PluginMeta, *PluginMetaList] +type MetaClient struct { + client *resource.TypedClient[*Meta, *MetaList] } -func NewPluginMetaClient(client resource.Client) *PluginMetaClient { - return &PluginMetaClient{ - client: resource.NewTypedClient[*PluginMeta, *PluginMetaList](client, PluginMetaKind()), +func NewMetaClient(client resource.Client) *MetaClient { + return &MetaClient{ + client: resource.NewTypedClient[*Meta, *MetaList](client, MetaKind()), } } -func NewPluginMetaClientFromGenerator(generator resource.ClientGenerator) (*PluginMetaClient, error) { - c, err := generator.ClientFor(PluginMetaKind()) +func NewMetaClientFromGenerator(generator resource.ClientGenerator) (*MetaClient, error) { + c, err := generator.ClientFor(MetaKind()) if err != nil { return nil, err } - return NewPluginMetaClient(c), nil + return NewMetaClient(c), nil } -func (c *PluginMetaClient) Get(ctx context.Context, identifier resource.Identifier) (*PluginMeta, error) { +func (c *MetaClient) Get(ctx context.Context, identifier resource.Identifier) (*Meta, error) { return c.client.Get(ctx, identifier) } -func (c *PluginMetaClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*PluginMetaList, error) { +func (c *MetaClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (*MetaList, error) { return c.client.List(ctx, namespace, opts) } -func (c *PluginMetaClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*PluginMetaList, error) { +func (c *MetaClient) ListAll(ctx context.Context, namespace string, opts resource.ListOptions) (*MetaList, error) { resp, err := c.client.List(ctx, namespace, resource.ListOptions{ ResourceVersion: opts.ResourceVersion, Limit: opts.Limit, @@ -61,25 +61,25 @@ func (c *PluginMetaClient) ListAll(ctx context.Context, namespace string, opts r return resp, nil } -func (c *PluginMetaClient) Create(ctx context.Context, obj *PluginMeta, opts resource.CreateOptions) (*PluginMeta, error) { +func (c *MetaClient) Create(ctx context.Context, obj *Meta, opts resource.CreateOptions) (*Meta, error) { // Make sure apiVersion and kind are set obj.APIVersion = GroupVersion.Identifier() - obj.Kind = PluginMetaKind().Kind() + obj.Kind = MetaKind().Kind() return c.client.Create(ctx, obj, opts) } -func (c *PluginMetaClient) Update(ctx context.Context, obj *PluginMeta, opts resource.UpdateOptions) (*PluginMeta, error) { +func (c *MetaClient) Update(ctx context.Context, obj *Meta, opts resource.UpdateOptions) (*Meta, error) { return c.client.Update(ctx, obj, opts) } -func (c *PluginMetaClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*PluginMeta, error) { +func (c *MetaClient) Patch(ctx context.Context, identifier resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions) (*Meta, error) { return c.client.Patch(ctx, identifier, req, opts) } -func (c *PluginMetaClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus PluginMetaStatus, opts resource.UpdateOptions) (*PluginMeta, error) { - return c.client.Update(ctx, &PluginMeta{ +func (c *MetaClient) UpdateStatus(ctx context.Context, identifier resource.Identifier, newStatus MetaStatus, opts resource.UpdateOptions) (*Meta, error) { + return c.client.Update(ctx, &Meta{ TypeMeta: metav1.TypeMeta{ - Kind: PluginMetaKind().Kind(), + Kind: MetaKind().Kind(), APIVersion: GroupVersion.Identifier(), }, ObjectMeta: metav1.ObjectMeta{ @@ -94,6 +94,6 @@ func (c *PluginMetaClient) UpdateStatus(ctx context.Context, identifier resource }) } -func (c *PluginMetaClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error { +func (c *MetaClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error { return c.client.Delete(ctx, identifier, opts) } diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_codec_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_codec_gen.go similarity index 56% rename from apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_codec_gen.go rename to apps/plugins/pkg/apis/plugins/v0alpha1/meta_codec_gen.go index 77fb6f918a2..c152eb63e79 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_codec_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_codec_gen.go @@ -11,18 +11,18 @@ import ( "github.com/grafana/grafana-app-sdk/resource" ) -// PluginMetaJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding -type PluginMetaJSONCodec struct{} +// MetaJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding +type MetaJSONCodec struct{} // Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` -func (*PluginMetaJSONCodec) Read(reader io.Reader, into resource.Object) error { +func (*MetaJSONCodec) Read(reader io.Reader, into resource.Object) error { return json.NewDecoder(reader).Decode(into) } // Write writes JSON-encoded bytes into `writer` marshaled from `from` -func (*PluginMetaJSONCodec) Write(writer io.Writer, from resource.Object) error { +func (*MetaJSONCodec) Write(writer io.Writer, from resource.Object) error { return json.NewEncoder(writer).Encode(from) } // Interface compliance checks -var _ resource.Codec = &PluginMetaJSONCodec{} +var _ resource.Codec = &MetaJSONCodec{} diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_metadata_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_metadata_gen.go similarity index 85% rename from apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_metadata_gen.go rename to apps/plugins/pkg/apis/plugins/v0alpha1/meta_metadata_gen.go index 7d3b3c9c6b8..9de0658352f 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_metadata_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_metadata_gen.go @@ -9,7 +9,7 @@ import ( // metadata contains embedded CommonMetadata and can be extended with custom string fields // TODO: use CommonMetadata instead of redefining here; currently needs to be defined here // without external reference as using the CommonMetadata reference breaks thema codegen. -type PluginMetaMetadata struct { +type MetaMetadata struct { UpdateTimestamp time.Time `json:"updateTimestamp"` CreatedBy string `json:"createdBy"` Uid string `json:"uid"` @@ -22,9 +22,9 @@ type PluginMetaMetadata struct { Labels map[string]string `json:"labels"` } -// NewPluginMetaMetadata creates a new PluginMetaMetadata object. -func NewPluginMetaMetadata() *PluginMetaMetadata { - return &PluginMetaMetadata{ +// NewMetaMetadata creates a new MetaMetadata object. +func NewMetaMetadata() *MetaMetadata { + return &MetaMetadata{ Finalizers: []string{}, Labels: map[string]string{}, } diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_object_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_object_gen.go similarity index 68% rename from apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_object_gen.go rename to apps/plugins/pkg/apis/plugins/v0alpha1/meta_object_gen.go index dac431ebf12..e42a1ad5d80 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_object_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_object_gen.go @@ -15,22 +15,29 @@ import ( ) // +k8s:openapi-gen=true -type PluginMeta struct { +type Meta struct { metav1.TypeMeta `json:",inline" yaml:",inline"` metav1.ObjectMeta `json:"metadata" yaml:"metadata"` - // Spec is the spec of the PluginMeta - Spec PluginMetaSpec `json:"spec" yaml:"spec"` + // Spec is the spec of the Meta + Spec MetaSpec `json:"spec" yaml:"spec"` - Status PluginMetaStatus `json:"status" yaml:"status"` + Status MetaStatus `json:"status" yaml:"status"` } -func (o *PluginMeta) GetSpec() any { +func NewMeta() *Meta { + return &Meta{ + Spec: *NewMetaSpec(), + Status: *NewMetaStatus(), + } +} + +func (o *Meta) GetSpec() any { return o.Spec } -func (o *PluginMeta) SetSpec(spec any) error { - cast, ok := spec.(PluginMetaSpec) +func (o *Meta) SetSpec(spec any) error { + cast, ok := spec.(MetaSpec) if !ok { return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) } @@ -38,13 +45,13 @@ func (o *PluginMeta) SetSpec(spec any) error { return nil } -func (o *PluginMeta) GetSubresources() map[string]any { +func (o *Meta) GetSubresources() map[string]any { return map[string]any{ "status": o.Status, } } -func (o *PluginMeta) GetSubresource(name string) (any, bool) { +func (o *Meta) GetSubresource(name string) (any, bool) { switch name { case "status": return o.Status, true @@ -53,12 +60,12 @@ func (o *PluginMeta) GetSubresource(name string) (any, bool) { } } -func (o *PluginMeta) SetSubresource(name string, value any) error { +func (o *Meta) SetSubresource(name string, value any) error { switch name { case "status": - cast, ok := value.(PluginMetaStatus) + cast, ok := value.(MetaStatus) if !ok { - return fmt.Errorf("cannot set status type %#v, not of type PluginMetaStatus", value) + return fmt.Errorf("cannot set status type %#v, not of type MetaStatus", value) } o.Status = cast return nil @@ -67,7 +74,7 @@ func (o *PluginMeta) SetSubresource(name string, value any) error { } } -func (o *PluginMeta) GetStaticMetadata() resource.StaticMetadata { +func (o *Meta) GetStaticMetadata() resource.StaticMetadata { gvk := o.GroupVersionKind() return resource.StaticMetadata{ Name: o.ObjectMeta.Name, @@ -78,7 +85,7 @@ func (o *PluginMeta) GetStaticMetadata() resource.StaticMetadata { } } -func (o *PluginMeta) SetStaticMetadata(metadata resource.StaticMetadata) { +func (o *Meta) SetStaticMetadata(metadata resource.StaticMetadata) { o.Name = metadata.Name o.Namespace = metadata.Namespace o.SetGroupVersionKind(schema.GroupVersionKind{ @@ -88,7 +95,7 @@ func (o *PluginMeta) SetStaticMetadata(metadata resource.StaticMetadata) { }) } -func (o *PluginMeta) GetCommonMetadata() resource.CommonMetadata { +func (o *Meta) GetCommonMetadata() resource.CommonMetadata { dt := o.DeletionTimestamp var deletionTimestamp *time.Time if dt != nil { @@ -120,7 +127,7 @@ func (o *PluginMeta) GetCommonMetadata() resource.CommonMetadata { } } -func (o *PluginMeta) SetCommonMetadata(metadata resource.CommonMetadata) { +func (o *Meta) SetCommonMetadata(metadata resource.CommonMetadata) { o.UID = types.UID(metadata.UID) o.ResourceVersion = metadata.ResourceVersion o.Generation = metadata.Generation @@ -165,7 +172,7 @@ func (o *PluginMeta) SetCommonMetadata(metadata resource.CommonMetadata) { } } -func (o *PluginMeta) GetCreatedBy() string { +func (o *Meta) GetCreatedBy() string { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -173,7 +180,7 @@ func (o *PluginMeta) GetCreatedBy() string { return o.ObjectMeta.Annotations["grafana.com/createdBy"] } -func (o *PluginMeta) SetCreatedBy(createdBy string) { +func (o *Meta) SetCreatedBy(createdBy string) { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -181,7 +188,7 @@ func (o *PluginMeta) SetCreatedBy(createdBy string) { o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy } -func (o *PluginMeta) GetUpdateTimestamp() time.Time { +func (o *Meta) GetUpdateTimestamp() time.Time { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -190,7 +197,7 @@ func (o *PluginMeta) GetUpdateTimestamp() time.Time { return parsed } -func (o *PluginMeta) SetUpdateTimestamp(updateTimestamp time.Time) { +func (o *Meta) SetUpdateTimestamp(updateTimestamp time.Time) { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -198,7 +205,7 @@ func (o *PluginMeta) SetUpdateTimestamp(updateTimestamp time.Time) { o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) } -func (o *PluginMeta) GetUpdatedBy() string { +func (o *Meta) GetUpdatedBy() string { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -206,7 +213,7 @@ func (o *PluginMeta) GetUpdatedBy() string { return o.ObjectMeta.Annotations["grafana.com/updatedBy"] } -func (o *PluginMeta) SetUpdatedBy(updatedBy string) { +func (o *Meta) SetUpdatedBy(updatedBy string) { if o.ObjectMeta.Annotations == nil { o.ObjectMeta.Annotations = make(map[string]string) } @@ -214,21 +221,21 @@ func (o *PluginMeta) SetUpdatedBy(updatedBy string) { o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy } -func (o *PluginMeta) Copy() resource.Object { +func (o *Meta) Copy() resource.Object { return resource.CopyObject(o) } -func (o *PluginMeta) DeepCopyObject() runtime.Object { +func (o *Meta) DeepCopyObject() runtime.Object { return o.Copy() } -func (o *PluginMeta) DeepCopy() *PluginMeta { - cpy := &PluginMeta{} +func (o *Meta) DeepCopy() *Meta { + cpy := &Meta{} o.DeepCopyInto(cpy) return cpy } -func (o *PluginMeta) DeepCopyInto(dst *PluginMeta) { +func (o *Meta) DeepCopyInto(dst *Meta) { dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion dst.TypeMeta.Kind = o.TypeMeta.Kind o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta) @@ -237,34 +244,34 @@ func (o *PluginMeta) DeepCopyInto(dst *PluginMeta) { } // Interface compliance compile-time check -var _ resource.Object = &PluginMeta{} +var _ resource.Object = &Meta{} // +k8s:openapi-gen=true -type PluginMetaList struct { +type MetaList struct { metav1.TypeMeta `json:",inline" yaml:",inline"` metav1.ListMeta `json:"metadata" yaml:"metadata"` - Items []PluginMeta `json:"items" yaml:"items"` + Items []Meta `json:"items" yaml:"items"` } -func (o *PluginMetaList) DeepCopyObject() runtime.Object { +func (o *MetaList) DeepCopyObject() runtime.Object { return o.Copy() } -func (o *PluginMetaList) Copy() resource.ListObject { - cpy := &PluginMetaList{ +func (o *MetaList) Copy() resource.ListObject { + cpy := &MetaList{ TypeMeta: o.TypeMeta, - Items: make([]PluginMeta, len(o.Items)), + Items: make([]Meta, len(o.Items)), } o.ListMeta.DeepCopyInto(&cpy.ListMeta) for i := 0; i < len(o.Items); i++ { - if item, ok := o.Items[i].Copy().(*PluginMeta); ok { + if item, ok := o.Items[i].Copy().(*Meta); ok { cpy.Items[i] = *item } } return cpy } -func (o *PluginMetaList) GetItems() []resource.Object { +func (o *MetaList) GetItems() []resource.Object { items := make([]resource.Object, len(o.Items)) for i := 0; i < len(o.Items); i++ { items[i] = &o.Items[i] @@ -272,48 +279,48 @@ func (o *PluginMetaList) GetItems() []resource.Object { return items } -func (o *PluginMetaList) SetItems(items []resource.Object) { - o.Items = make([]PluginMeta, len(items)) +func (o *MetaList) SetItems(items []resource.Object) { + o.Items = make([]Meta, len(items)) for i := 0; i < len(items); i++ { - o.Items[i] = *items[i].(*PluginMeta) + o.Items[i] = *items[i].(*Meta) } } -func (o *PluginMetaList) DeepCopy() *PluginMetaList { - cpy := &PluginMetaList{} +func (o *MetaList) DeepCopy() *MetaList { + cpy := &MetaList{} o.DeepCopyInto(cpy) return cpy } -func (o *PluginMetaList) DeepCopyInto(dst *PluginMetaList) { +func (o *MetaList) DeepCopyInto(dst *MetaList) { resource.CopyObjectInto(dst, o) } // Interface compliance compile-time check -var _ resource.ListObject = &PluginMetaList{} +var _ resource.ListObject = &MetaList{} // Copy methods for all subresource types // DeepCopy creates a full deep copy of Spec -func (s *PluginMetaSpec) DeepCopy() *PluginMetaSpec { - cpy := &PluginMetaSpec{} +func (s *MetaSpec) DeepCopy() *MetaSpec { + cpy := &MetaSpec{} s.DeepCopyInto(cpy) return cpy } // DeepCopyInto deep copies Spec into another Spec object -func (s *PluginMetaSpec) DeepCopyInto(dst *PluginMetaSpec) { +func (s *MetaSpec) DeepCopyInto(dst *MetaSpec) { resource.CopyObjectInto(dst, s) } -// DeepCopy creates a full deep copy of PluginMetaStatus -func (s *PluginMetaStatus) DeepCopy() *PluginMetaStatus { - cpy := &PluginMetaStatus{} +// DeepCopy creates a full deep copy of MetaStatus +func (s *MetaStatus) DeepCopy() *MetaStatus { + cpy := &MetaStatus{} s.DeepCopyInto(cpy) return cpy } -// DeepCopyInto deep copies PluginMetaStatus into another PluginMetaStatus object -func (s *PluginMetaStatus) DeepCopyInto(dst *PluginMetaStatus) { +// DeepCopyInto deep copies MetaStatus into another MetaStatus object +func (s *MetaStatus) DeepCopyInto(dst *MetaStatus) { resource.CopyObjectInto(dst, s) } diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/meta_schema_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_schema_gen.go new file mode 100644 index 00000000000..38b45140ff6 --- /dev/null +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_schema_gen.go @@ -0,0 +1,34 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" +) + +// schema is unexported to prevent accidental overwrites +var ( + schemaMeta = resource.NewSimpleSchema("plugins.grafana.app", "v0alpha1", NewMeta(), &MetaList{}, resource.WithKind("Meta"), + resource.WithPlural("metas"), resource.WithScope(resource.NamespacedScope)) + kindMeta = resource.Kind{ + Schema: schemaMeta, + Codecs: map[resource.KindEncoding]resource.Codec{ + resource.KindEncodingJSON: &MetaJSONCodec{}, + }, + } +) + +// Kind returns a resource.Kind for this Schema with a JSON codec +func MetaKind() resource.Kind { + return kindMeta +} + +// Schema returns a resource.SimpleSchema representation of Meta +func MetaSchema() *resource.SimpleSchema { + return schemaMeta +} + +// Interface compliance checks +var _ resource.Schema = kindMeta diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/meta_spec_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_spec_gen.go new file mode 100644 index 00000000000..631febbe2fa --- /dev/null +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_spec_gen.go @@ -0,0 +1,572 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// JSON configuration schema for Grafana plugins +// Converted from: https://github.com/grafana/grafana/blob/main/docs/sources/developers/plugins/plugin.schema.json +// +k8s:openapi-gen=true +type MetaJSONData struct { + // Unique name of the plugin + Id string `json:"id"` + // Plugin type + Type MetaJSONDataType `json:"type"` + // Human-readable name of the plugin + Name string `json:"name"` + // Metadata for the plugin + Info MetaInfo `json:"info"` + // Dependency information + Dependencies MetaDependencies `json:"dependencies"` + // Optional fields + Alerting *bool `json:"alerting,omitempty"` + Annotations *bool `json:"annotations,omitempty"` + AutoEnabled *bool `json:"autoEnabled,omitempty"` + Backend *bool `json:"backend,omitempty"` + BuildMode *string `json:"buildMode,omitempty"` + BuiltIn *bool `json:"builtIn,omitempty"` + Category *MetaJSONDataCategory `json:"category,omitempty"` + EnterpriseFeatures *MetaEnterpriseFeatures `json:"enterpriseFeatures,omitempty"` + Executable *string `json:"executable,omitempty"` + HideFromList *bool `json:"hideFromList,omitempty"` + // +listType=atomic + Includes []MetaInclude `json:"includes,omitempty"` + Logs *bool `json:"logs,omitempty"` + Metrics *bool `json:"metrics,omitempty"` + MultiValueFilterOperators *bool `json:"multiValueFilterOperators,omitempty"` + PascalName *string `json:"pascalName,omitempty"` + Preload *bool `json:"preload,omitempty"` + QueryOptions *MetaQueryOptions `json:"queryOptions,omitempty"` + // +listType=atomic + Routes []MetaRoute `json:"routes,omitempty"` + SkipDataQuery *bool `json:"skipDataQuery,omitempty"` + State *MetaJSONDataState `json:"state,omitempty"` + Streaming *bool `json:"streaming,omitempty"` + Suggestions *bool `json:"suggestions,omitempty"` + Tracing *bool `json:"tracing,omitempty"` + Iam *MetaIAM `json:"iam,omitempty"` + // +listType=atomic + Roles []MetaRole `json:"roles,omitempty"` + Extensions *MetaExtensions `json:"extensions,omitempty"` +} + +// NewMetaJSONData creates a new MetaJSONData object. +func NewMetaJSONData() *MetaJSONData { + return &MetaJSONData{ + Info: *NewMetaInfo(), + Dependencies: *NewMetaDependencies(), + } +} + +// +k8s:openapi-gen=true +type MetaInfo struct { + // Required fields + // +listType=set + Keywords []string `json:"keywords"` + Logos MetaV0alpha1InfoLogos `json:"logos"` + Updated string `json:"updated"` + Version string `json:"version"` + // Optional fields + Author *MetaV0alpha1InfoAuthor `json:"author,omitempty"` + Description *string `json:"description,omitempty"` + // +listType=atomic + Links []MetaV0alpha1InfoLinks `json:"links,omitempty"` + // +listType=atomic + Screenshots []MetaV0alpha1InfoScreenshots `json:"screenshots,omitempty"` +} + +// NewMetaInfo creates a new MetaInfo object. +func NewMetaInfo() *MetaInfo { + return &MetaInfo{ + Keywords: []string{}, + Logos: *NewMetaV0alpha1InfoLogos(), + } +} + +// +k8s:openapi-gen=true +type MetaDependencies struct { + // Required field + GrafanaDependency string `json:"grafanaDependency"` + // Optional fields + GrafanaVersion *string `json:"grafanaVersion,omitempty"` + // +listType=set + // +listMapKey=id + Plugins []MetaV0alpha1DependenciesPlugins `json:"plugins,omitempty"` + Extensions *MetaV0alpha1DependenciesExtensions `json:"extensions,omitempty"` +} + +// NewMetaDependencies creates a new MetaDependencies object. +func NewMetaDependencies() *MetaDependencies { + return &MetaDependencies{} +} + +// +k8s:openapi-gen=true +type MetaEnterpriseFeatures struct { + // Allow additional properties + HealthDiagnosticsErrors *bool `json:"healthDiagnosticsErrors,omitempty"` +} + +// NewMetaEnterpriseFeatures creates a new MetaEnterpriseFeatures object. +func NewMetaEnterpriseFeatures() *MetaEnterpriseFeatures { + return &MetaEnterpriseFeatures{ + HealthDiagnosticsErrors: (func(input bool) *bool { return &input })(false), + } +} + +// +k8s:openapi-gen=true +type MetaInclude struct { + Uid *string `json:"uid,omitempty"` + Type *MetaIncludeType `json:"type,omitempty"` + Name *string `json:"name,omitempty"` + Component *string `json:"component,omitempty"` + Role *MetaIncludeRole `json:"role,omitempty"` + Action *string `json:"action,omitempty"` + Path *string `json:"path,omitempty"` + AddToNav *bool `json:"addToNav,omitempty"` + DefaultNav *bool `json:"defaultNav,omitempty"` + Icon *string `json:"icon,omitempty"` +} + +// NewMetaInclude creates a new MetaInclude object. +func NewMetaInclude() *MetaInclude { + return &MetaInclude{} +} + +// +k8s:openapi-gen=true +type MetaQueryOptions struct { + MaxDataPoints *bool `json:"maxDataPoints,omitempty"` + MinInterval *bool `json:"minInterval,omitempty"` + CacheTimeout *bool `json:"cacheTimeout,omitempty"` +} + +// NewMetaQueryOptions creates a new MetaQueryOptions object. +func NewMetaQueryOptions() *MetaQueryOptions { + return &MetaQueryOptions{} +} + +// +k8s:openapi-gen=true +type MetaRoute struct { + Path *string `json:"path,omitempty"` + Method *string `json:"method,omitempty"` + Url *string `json:"url,omitempty"` + ReqSignedIn *bool `json:"reqSignedIn,omitempty"` + ReqRole *string `json:"reqRole,omitempty"` + ReqAction *string `json:"reqAction,omitempty"` + // +listType=atomic + Headers []string `json:"headers,omitempty"` + Body map[string]interface{} `json:"body,omitempty"` + TokenAuth *MetaV0alpha1RouteTokenAuth `json:"tokenAuth,omitempty"` + JwtTokenAuth *MetaV0alpha1RouteJwtTokenAuth `json:"jwtTokenAuth,omitempty"` + // +listType=atomic + UrlParams []MetaV0alpha1RouteUrlParams `json:"urlParams,omitempty"` +} + +// NewMetaRoute creates a new MetaRoute object. +func NewMetaRoute() *MetaRoute { + return &MetaRoute{} +} + +// +k8s:openapi-gen=true +type MetaIAM struct { + // +listType=atomic + Permissions []MetaV0alpha1IAMPermissions `json:"permissions,omitempty"` +} + +// NewMetaIAM creates a new MetaIAM object. +func NewMetaIAM() *MetaIAM { + return &MetaIAM{} +} + +// +k8s:openapi-gen=true +type MetaRole struct { + Role *MetaV0alpha1RoleRole `json:"role,omitempty"` + // +listType=set + Grants []string `json:"grants,omitempty"` +} + +// NewMetaRole creates a new MetaRole object. +func NewMetaRole() *MetaRole { + return &MetaRole{} +} + +// +k8s:openapi-gen=true +type MetaExtensions struct { + // +listType=atomic + AddedComponents []MetaV0alpha1ExtensionsAddedComponents `json:"addedComponents,omitempty"` + // +listType=atomic + AddedLinks []MetaV0alpha1ExtensionsAddedLinks `json:"addedLinks,omitempty"` + // +listType=atomic + AddedFunctions []MetaV0alpha1ExtensionsAddedFunctions `json:"addedFunctions,omitempty"` + // +listType=set + // +listMapKey=id + ExposedComponents []MetaV0alpha1ExtensionsExposedComponents `json:"exposedComponents,omitempty"` + // +listType=set + // +listMapKey=id + ExtensionPoints []MetaV0alpha1ExtensionsExtensionPoints `json:"extensionPoints,omitempty"` +} + +// NewMetaExtensions creates a new MetaExtensions object. +func NewMetaExtensions() *MetaExtensions { + return &MetaExtensions{} +} + +// +k8s:openapi-gen=true +type MetaSpec struct { + PluginJson MetaJSONData `json:"pluginJson"` + Class MetaSpecClass `json:"class"` + Module *MetaV0alpha1SpecModule `json:"module,omitempty"` + BaseURL *string `json:"baseURL,omitempty"` + Signature *MetaV0alpha1SpecSignature `json:"signature,omitempty"` + Angular *MetaV0alpha1SpecAngular `json:"angular,omitempty"` + Translations map[string]string `json:"translations,omitempty"` + // +listType=atomic + Children []string `json:"children,omitempty"` +} + +// NewMetaSpec creates a new MetaSpec object. +func NewMetaSpec() *MetaSpec { + return &MetaSpec{ + PluginJson: *NewMetaJSONData(), + } +} + +// +k8s:openapi-gen=true +type MetaV0alpha1InfoLogos struct { + Small string `json:"small"` + Large string `json:"large"` +} + +// NewMetaV0alpha1InfoLogos creates a new MetaV0alpha1InfoLogos object. +func NewMetaV0alpha1InfoLogos() *MetaV0alpha1InfoLogos { + return &MetaV0alpha1InfoLogos{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1InfoAuthor struct { + Name *string `json:"name,omitempty"` + Email *string `json:"email,omitempty"` + Url *string `json:"url,omitempty"` +} + +// NewMetaV0alpha1InfoAuthor creates a new MetaV0alpha1InfoAuthor object. +func NewMetaV0alpha1InfoAuthor() *MetaV0alpha1InfoAuthor { + return &MetaV0alpha1InfoAuthor{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1InfoLinks struct { + Name *string `json:"name,omitempty"` + Url *string `json:"url,omitempty"` +} + +// NewMetaV0alpha1InfoLinks creates a new MetaV0alpha1InfoLinks object. +func NewMetaV0alpha1InfoLinks() *MetaV0alpha1InfoLinks { + return &MetaV0alpha1InfoLinks{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1InfoScreenshots struct { + Name *string `json:"name,omitempty"` + Path *string `json:"path,omitempty"` +} + +// NewMetaV0alpha1InfoScreenshots creates a new MetaV0alpha1InfoScreenshots object. +func NewMetaV0alpha1InfoScreenshots() *MetaV0alpha1InfoScreenshots { + return &MetaV0alpha1InfoScreenshots{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1DependenciesPlugins struct { + Id string `json:"id"` + Type MetaV0alpha1DependenciesPluginsType `json:"type"` + Name string `json:"name"` +} + +// NewMetaV0alpha1DependenciesPlugins creates a new MetaV0alpha1DependenciesPlugins object. +func NewMetaV0alpha1DependenciesPlugins() *MetaV0alpha1DependenciesPlugins { + return &MetaV0alpha1DependenciesPlugins{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1DependenciesExtensions struct { + // +listType=set + ExposedComponents []string `json:"exposedComponents,omitempty"` +} + +// NewMetaV0alpha1DependenciesExtensions creates a new MetaV0alpha1DependenciesExtensions object. +func NewMetaV0alpha1DependenciesExtensions() *MetaV0alpha1DependenciesExtensions { + return &MetaV0alpha1DependenciesExtensions{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1RouteTokenAuth struct { + Url *string `json:"url,omitempty"` + // +listType=set + Scopes []string `json:"scopes,omitempty"` + Params map[string]interface{} `json:"params,omitempty"` +} + +// NewMetaV0alpha1RouteTokenAuth creates a new MetaV0alpha1RouteTokenAuth object. +func NewMetaV0alpha1RouteTokenAuth() *MetaV0alpha1RouteTokenAuth { + return &MetaV0alpha1RouteTokenAuth{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1RouteJwtTokenAuth struct { + Url *string `json:"url,omitempty"` + // +listType=set + Scopes []string `json:"scopes,omitempty"` + Params map[string]interface{} `json:"params,omitempty"` +} + +// NewMetaV0alpha1RouteJwtTokenAuth creates a new MetaV0alpha1RouteJwtTokenAuth object. +func NewMetaV0alpha1RouteJwtTokenAuth() *MetaV0alpha1RouteJwtTokenAuth { + return &MetaV0alpha1RouteJwtTokenAuth{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1RouteUrlParams struct { + Name *string `json:"name,omitempty"` + Content *string `json:"content,omitempty"` +} + +// NewMetaV0alpha1RouteUrlParams creates a new MetaV0alpha1RouteUrlParams object. +func NewMetaV0alpha1RouteUrlParams() *MetaV0alpha1RouteUrlParams { + return &MetaV0alpha1RouteUrlParams{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1IAMPermissions struct { + Action *string `json:"action,omitempty"` + Scope *string `json:"scope,omitempty"` +} + +// NewMetaV0alpha1IAMPermissions creates a new MetaV0alpha1IAMPermissions object. +func NewMetaV0alpha1IAMPermissions() *MetaV0alpha1IAMPermissions { + return &MetaV0alpha1IAMPermissions{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1RoleRolePermissions struct { + Action *string `json:"action,omitempty"` + Scope *string `json:"scope,omitempty"` +} + +// NewMetaV0alpha1RoleRolePermissions creates a new MetaV0alpha1RoleRolePermissions object. +func NewMetaV0alpha1RoleRolePermissions() *MetaV0alpha1RoleRolePermissions { + return &MetaV0alpha1RoleRolePermissions{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1RoleRole struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + // +listType=atomic + Permissions []MetaV0alpha1RoleRolePermissions `json:"permissions,omitempty"` +} + +// NewMetaV0alpha1RoleRole creates a new MetaV0alpha1RoleRole object. +func NewMetaV0alpha1RoleRole() *MetaV0alpha1RoleRole { + return &MetaV0alpha1RoleRole{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1ExtensionsAddedComponents struct { + // +listType=set + Targets []string `json:"targets"` + Title string `json:"title"` + Description *string `json:"description,omitempty"` +} + +// NewMetaV0alpha1ExtensionsAddedComponents creates a new MetaV0alpha1ExtensionsAddedComponents object. +func NewMetaV0alpha1ExtensionsAddedComponents() *MetaV0alpha1ExtensionsAddedComponents { + return &MetaV0alpha1ExtensionsAddedComponents{ + Targets: []string{}, + } +} + +// +k8s:openapi-gen=true +type MetaV0alpha1ExtensionsAddedLinks struct { + // +listType=set + Targets []string `json:"targets"` + Title string `json:"title"` + Description *string `json:"description,omitempty"` +} + +// NewMetaV0alpha1ExtensionsAddedLinks creates a new MetaV0alpha1ExtensionsAddedLinks object. +func NewMetaV0alpha1ExtensionsAddedLinks() *MetaV0alpha1ExtensionsAddedLinks { + return &MetaV0alpha1ExtensionsAddedLinks{ + Targets: []string{}, + } +} + +// +k8s:openapi-gen=true +type MetaV0alpha1ExtensionsAddedFunctions struct { + // +listType=set + Targets []string `json:"targets"` + Title string `json:"title"` + Description *string `json:"description,omitempty"` +} + +// NewMetaV0alpha1ExtensionsAddedFunctions creates a new MetaV0alpha1ExtensionsAddedFunctions object. +func NewMetaV0alpha1ExtensionsAddedFunctions() *MetaV0alpha1ExtensionsAddedFunctions { + return &MetaV0alpha1ExtensionsAddedFunctions{ + Targets: []string{}, + } +} + +// +k8s:openapi-gen=true +type MetaV0alpha1ExtensionsExposedComponents struct { + Id string `json:"id"` + Title *string `json:"title,omitempty"` + Description *string `json:"description,omitempty"` +} + +// NewMetaV0alpha1ExtensionsExposedComponents creates a new MetaV0alpha1ExtensionsExposedComponents object. +func NewMetaV0alpha1ExtensionsExposedComponents() *MetaV0alpha1ExtensionsExposedComponents { + return &MetaV0alpha1ExtensionsExposedComponents{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1ExtensionsExtensionPoints struct { + Id string `json:"id"` + Title *string `json:"title,omitempty"` + Description *string `json:"description,omitempty"` +} + +// NewMetaV0alpha1ExtensionsExtensionPoints creates a new MetaV0alpha1ExtensionsExtensionPoints object. +func NewMetaV0alpha1ExtensionsExtensionPoints() *MetaV0alpha1ExtensionsExtensionPoints { + return &MetaV0alpha1ExtensionsExtensionPoints{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1SpecModule struct { + Path string `json:"path"` + Hash *string `json:"hash,omitempty"` + LoadingStrategy *MetaV0alpha1SpecModuleLoadingStrategy `json:"loadingStrategy,omitempty"` +} + +// NewMetaV0alpha1SpecModule creates a new MetaV0alpha1SpecModule object. +func NewMetaV0alpha1SpecModule() *MetaV0alpha1SpecModule { + return &MetaV0alpha1SpecModule{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1SpecSignature struct { + Status MetaV0alpha1SpecSignatureStatus `json:"status"` + Type *MetaV0alpha1SpecSignatureType `json:"type,omitempty"` + Org *string `json:"org,omitempty"` +} + +// NewMetaV0alpha1SpecSignature creates a new MetaV0alpha1SpecSignature object. +func NewMetaV0alpha1SpecSignature() *MetaV0alpha1SpecSignature { + return &MetaV0alpha1SpecSignature{} +} + +// +k8s:openapi-gen=true +type MetaV0alpha1SpecAngular struct { + Detected bool `json:"detected"` +} + +// NewMetaV0alpha1SpecAngular creates a new MetaV0alpha1SpecAngular object. +func NewMetaV0alpha1SpecAngular() *MetaV0alpha1SpecAngular { + return &MetaV0alpha1SpecAngular{} +} + +// +k8s:openapi-gen=true +type MetaJSONDataType string + +const ( + MetaJSONDataTypeApp MetaJSONDataType = "app" + MetaJSONDataTypeDatasource MetaJSONDataType = "datasource" + MetaJSONDataTypePanel MetaJSONDataType = "panel" + MetaJSONDataTypeRenderer MetaJSONDataType = "renderer" +) + +// +k8s:openapi-gen=true +type MetaJSONDataCategory string + +const ( + MetaJSONDataCategoryTsdb MetaJSONDataCategory = "tsdb" + MetaJSONDataCategoryLogging MetaJSONDataCategory = "logging" + MetaJSONDataCategoryCloud MetaJSONDataCategory = "cloud" + MetaJSONDataCategoryTracing MetaJSONDataCategory = "tracing" + MetaJSONDataCategoryProfiling MetaJSONDataCategory = "profiling" + MetaJSONDataCategorySql MetaJSONDataCategory = "sql" + MetaJSONDataCategoryEnterprise MetaJSONDataCategory = "enterprise" + MetaJSONDataCategoryIot MetaJSONDataCategory = "iot" + MetaJSONDataCategoryOther MetaJSONDataCategory = "other" +) + +// +k8s:openapi-gen=true +type MetaJSONDataState string + +const ( + MetaJSONDataStateAlpha MetaJSONDataState = "alpha" + MetaJSONDataStateBeta MetaJSONDataState = "beta" +) + +// +k8s:openapi-gen=true +type MetaIncludeType string + +const ( + MetaIncludeTypeDashboard MetaIncludeType = "dashboard" + MetaIncludeTypePage MetaIncludeType = "page" + MetaIncludeTypePanel MetaIncludeType = "panel" + MetaIncludeTypeDatasource MetaIncludeType = "datasource" +) + +// +k8s:openapi-gen=true +type MetaIncludeRole string + +const ( + MetaIncludeRoleAdmin MetaIncludeRole = "Admin" + MetaIncludeRoleEditor MetaIncludeRole = "Editor" + MetaIncludeRoleViewer MetaIncludeRole = "Viewer" + MetaIncludeRoleNone MetaIncludeRole = "None" +) + +// +k8s:openapi-gen=true +type MetaSpecClass string + +const ( + MetaSpecClassCore MetaSpecClass = "core" + MetaSpecClassExternal MetaSpecClass = "external" +) + +// +k8s:openapi-gen=true +type MetaV0alpha1DependenciesPluginsType string + +const ( + MetaV0alpha1DependenciesPluginsTypeApp MetaV0alpha1DependenciesPluginsType = "app" + MetaV0alpha1DependenciesPluginsTypeDatasource MetaV0alpha1DependenciesPluginsType = "datasource" + MetaV0alpha1DependenciesPluginsTypePanel MetaV0alpha1DependenciesPluginsType = "panel" +) + +// +k8s:openapi-gen=true +type MetaV0alpha1SpecModuleLoadingStrategy string + +const ( + MetaV0alpha1SpecModuleLoadingStrategyFetch MetaV0alpha1SpecModuleLoadingStrategy = "fetch" + MetaV0alpha1SpecModuleLoadingStrategyScript MetaV0alpha1SpecModuleLoadingStrategy = "script" +) + +// +k8s:openapi-gen=true +type MetaV0alpha1SpecSignatureStatus string + +const ( + MetaV0alpha1SpecSignatureStatusInternal MetaV0alpha1SpecSignatureStatus = "internal" + MetaV0alpha1SpecSignatureStatusValid MetaV0alpha1SpecSignatureStatus = "valid" + MetaV0alpha1SpecSignatureStatusInvalid MetaV0alpha1SpecSignatureStatus = "invalid" + MetaV0alpha1SpecSignatureStatusModified MetaV0alpha1SpecSignatureStatus = "modified" + MetaV0alpha1SpecSignatureStatusUnsigned MetaV0alpha1SpecSignatureStatus = "unsigned" +) + +// +k8s:openapi-gen=true +type MetaV0alpha1SpecSignatureType string + +const ( + MetaV0alpha1SpecSignatureTypeGrafana MetaV0alpha1SpecSignatureType = "grafana" + MetaV0alpha1SpecSignatureTypeCommercial MetaV0alpha1SpecSignatureType = "commercial" + MetaV0alpha1SpecSignatureTypeCommunity MetaV0alpha1SpecSignatureType = "community" + MetaV0alpha1SpecSignatureTypePrivate MetaV0alpha1SpecSignatureType = "private" + MetaV0alpha1SpecSignatureTypePrivateGlob MetaV0alpha1SpecSignatureType = "private-glob" +) diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_status_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_status_gen.go similarity index 52% rename from apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_status_gen.go rename to apps/plugins/pkg/apis/plugins/v0alpha1/meta_status_gen.go index 60fa37dbb32..5f37ac58fb7 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_status_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/meta_status_gen.go @@ -3,42 +3,42 @@ package v0alpha1 // +k8s:openapi-gen=true -type PluginMetastatusOperatorState struct { +type MetastatusOperatorState struct { // lastEvaluation is the ResourceVersion last evaluated LastEvaluation string `json:"lastEvaluation"` // state describes the state of the lastEvaluation. // It is limited to three possible states for machine evaluation. - State PluginMetaStatusOperatorStateState `json:"state"` + State MetaStatusOperatorStateState `json:"state"` // descriptiveState is an optional more descriptive state field which has no requirements on format DescriptiveState *string `json:"descriptiveState,omitempty"` // details contains any extra information that is operator-specific Details map[string]interface{} `json:"details,omitempty"` } -// NewPluginMetastatusOperatorState creates a new PluginMetastatusOperatorState object. -func NewPluginMetastatusOperatorState() *PluginMetastatusOperatorState { - return &PluginMetastatusOperatorState{} +// NewMetastatusOperatorState creates a new MetastatusOperatorState object. +func NewMetastatusOperatorState() *MetastatusOperatorState { + return &MetastatusOperatorState{} } // +k8s:openapi-gen=true -type PluginMetaStatus struct { +type MetaStatus struct { // operatorStates is a map of operator ID to operator state evaluations. // Any operator which consumes this kind SHOULD add its state evaluation information to this field. - OperatorStates map[string]PluginMetastatusOperatorState `json:"operatorStates,omitempty"` + OperatorStates map[string]MetastatusOperatorState `json:"operatorStates,omitempty"` // additionalFields is reserved for future use AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` } -// NewPluginMetaStatus creates a new PluginMetaStatus object. -func NewPluginMetaStatus() *PluginMetaStatus { - return &PluginMetaStatus{} +// NewMetaStatus creates a new MetaStatus object. +func NewMetaStatus() *MetaStatus { + return &MetaStatus{} } // +k8s:openapi-gen=true -type PluginMetaStatusOperatorStateState string +type MetaStatusOperatorStateState string const ( - PluginMetaStatusOperatorStateStateSuccess PluginMetaStatusOperatorStateState = "success" - PluginMetaStatusOperatorStateStateInProgress PluginMetaStatusOperatorStateState = "in_progress" - PluginMetaStatusOperatorStateStateFailed PluginMetaStatusOperatorStateState = "failed" + MetaStatusOperatorStateStateSuccess MetaStatusOperatorStateState = "success" + MetaStatusOperatorStateStateInProgress MetaStatusOperatorStateState = "in_progress" + MetaStatusOperatorStateStateFailed MetaStatusOperatorStateState = "failed" ) diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_object_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_object_gen.go index d2cdedba399..b92b11f4cba 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_object_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_object_gen.go @@ -25,6 +25,13 @@ type Plugin struct { Status PluginStatus `json:"status" yaml:"status"` } +func NewPlugin() *Plugin { + return &Plugin{ + Spec: *NewPluginSpec(), + Status: *NewPluginStatus(), + } +} + func (o *Plugin) GetSpec() any { return o.Spec } diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_schema_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_schema_gen.go index 97024275a1c..144ddd5af89 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_schema_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_schema_gen.go @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaPlugin = resource.NewSimpleSchema("plugins.grafana.app", "v0alpha1", &Plugin{}, &PluginList{}, resource.WithKind("Plugin"), + schemaPlugin = resource.NewSimpleSchema("plugins.grafana.app", "v0alpha1", NewPlugin(), &PluginList{}, resource.WithKind("Plugin"), resource.WithPlural("plugins"), resource.WithScope(resource.NamespacedScope)) kindPlugin = resource.Kind{ Schema: schemaPlugin, diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_spec_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_spec_gen.go index 9ae14bcbdc5..51f5440eb92 100644 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_spec_gen.go +++ b/apps/plugins/pkg/apis/plugins/v0alpha1/plugin_spec_gen.go @@ -4,21 +4,12 @@ package v0alpha1 // +k8s:openapi-gen=true type PluginSpec struct { - Id string `json:"id"` - Version string `json:"version"` - Url *string `json:"url,omitempty"` - Class PluginSpecClass `json:"class"` + Id string `json:"id"` + Version string `json:"version"` + Url *string `json:"url,omitempty"` } // NewPluginSpec creates a new PluginSpec object. func NewPluginSpec() *PluginSpec { return &PluginSpec{} } - -// +k8s:openapi-gen=true -type PluginSpecClass string - -const ( - PluginSpecClassCore PluginSpecClass = "core" - PluginSpecClassExternal PluginSpecClass = "external" -) diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_schema_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_schema_gen.go deleted file mode 100644 index a4022c8de97..00000000000 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_schema_gen.go +++ /dev/null @@ -1,34 +0,0 @@ -// -// Code generated by grafana-app-sdk. DO NOT EDIT. -// - -package v0alpha1 - -import ( - "github.com/grafana/grafana-app-sdk/resource" -) - -// schema is unexported to prevent accidental overwrites -var ( - schemaPluginMeta = resource.NewSimpleSchema("plugins.grafana.app", "v0alpha1", &PluginMeta{}, &PluginMetaList{}, resource.WithKind("PluginMeta"), - resource.WithPlural("pluginmetas"), resource.WithScope(resource.NamespacedScope)) - kindPluginMeta = resource.Kind{ - Schema: schemaPluginMeta, - Codecs: map[resource.KindEncoding]resource.Codec{ - resource.KindEncodingJSON: &PluginMetaJSONCodec{}, - }, - } -) - -// Kind returns a resource.Kind for this Schema with a JSON codec -func PluginMetaKind() resource.Kind { - return kindPluginMeta -} - -// Schema returns a resource.SimpleSchema representation of PluginMeta -func PluginMetaSchema() *resource.SimpleSchema { - return schemaPluginMeta -} - -// Interface compliance checks -var _ resource.Schema = kindPluginMeta diff --git a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_spec_gen.go b/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_spec_gen.go deleted file mode 100644 index 14a3b0515bd..00000000000 --- a/apps/plugins/pkg/apis/plugins/v0alpha1/pluginmeta_spec_gen.go +++ /dev/null @@ -1,474 +0,0 @@ -// Code generated - EDITING IS FUTILE. DO NOT EDIT. - -package v0alpha1 - -// JSON configuration schema for Grafana plugins -// Converted from: https://github.com/grafana/grafana/blob/main/docs/sources/developers/plugins/plugin.schema.json -// +k8s:openapi-gen=true -type PluginMetaJSONData struct { - // Unique name of the plugin - Id string `json:"id"` - // Plugin type - Type PluginMetaJSONDataType `json:"type"` - // Human-readable name of the plugin - Name string `json:"name"` - // Metadata for the plugin - Info PluginMetaInfo `json:"info"` - // Dependency information - Dependencies PluginMetaDependencies `json:"dependencies"` - // Optional fields - Alerting *bool `json:"alerting,omitempty"` - Annotations *bool `json:"annotations,omitempty"` - AutoEnabled *bool `json:"autoEnabled,omitempty"` - Backend *bool `json:"backend,omitempty"` - BuildMode *string `json:"buildMode,omitempty"` - BuiltIn *bool `json:"builtIn,omitempty"` - Category *PluginMetaJSONDataCategory `json:"category,omitempty"` - EnterpriseFeatures *PluginMetaEnterpriseFeatures `json:"enterpriseFeatures,omitempty"` - Executable *string `json:"executable,omitempty"` - HideFromList *bool `json:"hideFromList,omitempty"` - // +listType=atomic - Includes []PluginMetaInclude `json:"includes,omitempty"` - Logs *bool `json:"logs,omitempty"` - Metrics *bool `json:"metrics,omitempty"` - MultiValueFilterOperators *bool `json:"multiValueFilterOperators,omitempty"` - PascalName *string `json:"pascalName,omitempty"` - Preload *bool `json:"preload,omitempty"` - QueryOptions *PluginMetaQueryOptions `json:"queryOptions,omitempty"` - // +listType=atomic - Routes []PluginMetaRoute `json:"routes,omitempty"` - SkipDataQuery *bool `json:"skipDataQuery,omitempty"` - State *PluginMetaJSONDataState `json:"state,omitempty"` - Streaming *bool `json:"streaming,omitempty"` - Suggestions *bool `json:"suggestions,omitempty"` - Tracing *bool `json:"tracing,omitempty"` - Iam *PluginMetaIAM `json:"iam,omitempty"` - // +listType=atomic - Roles []PluginMetaRole `json:"roles,omitempty"` - Extensions *PluginMetaExtensions `json:"extensions,omitempty"` -} - -// NewPluginMetaJSONData creates a new PluginMetaJSONData object. -func NewPluginMetaJSONData() *PluginMetaJSONData { - return &PluginMetaJSONData{ - Info: *NewPluginMetaInfo(), - Dependencies: *NewPluginMetaDependencies(), - } -} - -// +k8s:openapi-gen=true -type PluginMetaInfo struct { - // Required fields - // +listType=set - Keywords []string `json:"keywords"` - Logos PluginMetaV0alpha1InfoLogos `json:"logos"` - Updated string `json:"updated"` - Version string `json:"version"` - // Optional fields - Author *PluginMetaV0alpha1InfoAuthor `json:"author,omitempty"` - Description *string `json:"description,omitempty"` - // +listType=atomic - Links []PluginMetaV0alpha1InfoLinks `json:"links,omitempty"` - // +listType=atomic - Screenshots []PluginMetaV0alpha1InfoScreenshots `json:"screenshots,omitempty"` -} - -// NewPluginMetaInfo creates a new PluginMetaInfo object. -func NewPluginMetaInfo() *PluginMetaInfo { - return &PluginMetaInfo{ - Keywords: []string{}, - Logos: *NewPluginMetaV0alpha1InfoLogos(), - } -} - -// +k8s:openapi-gen=true -type PluginMetaDependencies struct { - // Required field - GrafanaDependency string `json:"grafanaDependency"` - // Optional fields - GrafanaVersion *string `json:"grafanaVersion,omitempty"` - // +listType=set - // +listMapKey=id - Plugins []PluginMetaV0alpha1DependenciesPlugins `json:"plugins,omitempty"` - Extensions *PluginMetaV0alpha1DependenciesExtensions `json:"extensions,omitempty"` -} - -// NewPluginMetaDependencies creates a new PluginMetaDependencies object. -func NewPluginMetaDependencies() *PluginMetaDependencies { - return &PluginMetaDependencies{} -} - -// +k8s:openapi-gen=true -type PluginMetaEnterpriseFeatures struct { - // Allow additional properties - HealthDiagnosticsErrors *bool `json:"healthDiagnosticsErrors,omitempty"` -} - -// NewPluginMetaEnterpriseFeatures creates a new PluginMetaEnterpriseFeatures object. -func NewPluginMetaEnterpriseFeatures() *PluginMetaEnterpriseFeatures { - return &PluginMetaEnterpriseFeatures{ - HealthDiagnosticsErrors: (func(input bool) *bool { return &input })(false), - } -} - -// +k8s:openapi-gen=true -type PluginMetaInclude struct { - Uid *string `json:"uid,omitempty"` - Type *PluginMetaIncludeType `json:"type,omitempty"` - Name *string `json:"name,omitempty"` - Component *string `json:"component,omitempty"` - Role *PluginMetaIncludeRole `json:"role,omitempty"` - Action *string `json:"action,omitempty"` - Path *string `json:"path,omitempty"` - AddToNav *bool `json:"addToNav,omitempty"` - DefaultNav *bool `json:"defaultNav,omitempty"` - Icon *string `json:"icon,omitempty"` -} - -// NewPluginMetaInclude creates a new PluginMetaInclude object. -func NewPluginMetaInclude() *PluginMetaInclude { - return &PluginMetaInclude{} -} - -// +k8s:openapi-gen=true -type PluginMetaQueryOptions struct { - MaxDataPoints *bool `json:"maxDataPoints,omitempty"` - MinInterval *bool `json:"minInterval,omitempty"` - CacheTimeout *bool `json:"cacheTimeout,omitempty"` -} - -// NewPluginMetaQueryOptions creates a new PluginMetaQueryOptions object. -func NewPluginMetaQueryOptions() *PluginMetaQueryOptions { - return &PluginMetaQueryOptions{} -} - -// +k8s:openapi-gen=true -type PluginMetaRoute struct { - Path *string `json:"path,omitempty"` - Method *string `json:"method,omitempty"` - Url *string `json:"url,omitempty"` - ReqSignedIn *bool `json:"reqSignedIn,omitempty"` - ReqRole *string `json:"reqRole,omitempty"` - ReqAction *string `json:"reqAction,omitempty"` - // +listType=atomic - Headers []string `json:"headers,omitempty"` - Body map[string]interface{} `json:"body,omitempty"` - TokenAuth *PluginMetaV0alpha1RouteTokenAuth `json:"tokenAuth,omitempty"` - JwtTokenAuth *PluginMetaV0alpha1RouteJwtTokenAuth `json:"jwtTokenAuth,omitempty"` - // +listType=atomic - UrlParams []PluginMetaV0alpha1RouteUrlParams `json:"urlParams,omitempty"` -} - -// NewPluginMetaRoute creates a new PluginMetaRoute object. -func NewPluginMetaRoute() *PluginMetaRoute { - return &PluginMetaRoute{} -} - -// +k8s:openapi-gen=true -type PluginMetaIAM struct { - // +listType=atomic - Permissions []PluginMetaV0alpha1IAMPermissions `json:"permissions,omitempty"` -} - -// NewPluginMetaIAM creates a new PluginMetaIAM object. -func NewPluginMetaIAM() *PluginMetaIAM { - return &PluginMetaIAM{} -} - -// +k8s:openapi-gen=true -type PluginMetaRole struct { - Role *PluginMetaV0alpha1RoleRole `json:"role,omitempty"` - // +listType=set - Grants []string `json:"grants,omitempty"` -} - -// NewPluginMetaRole creates a new PluginMetaRole object. -func NewPluginMetaRole() *PluginMetaRole { - return &PluginMetaRole{} -} - -// +k8s:openapi-gen=true -type PluginMetaExtensions struct { - // +listType=atomic - AddedComponents []PluginMetaV0alpha1ExtensionsAddedComponents `json:"addedComponents,omitempty"` - // +listType=atomic - AddedLinks []PluginMetaV0alpha1ExtensionsAddedLinks `json:"addedLinks,omitempty"` - // +listType=set - // +listMapKey=id - ExposedComponents []PluginMetaV0alpha1ExtensionsExposedComponents `json:"exposedComponents,omitempty"` - // +listType=set - // +listMapKey=id - ExtensionPoints []PluginMetaV0alpha1ExtensionsExtensionPoints `json:"extensionPoints,omitempty"` -} - -// NewPluginMetaExtensions creates a new PluginMetaExtensions object. -func NewPluginMetaExtensions() *PluginMetaExtensions { - return &PluginMetaExtensions{} -} - -// +k8s:openapi-gen=true -type PluginMetaSpec struct { - PluginJSON PluginMetaJSONData `json:"pluginJSON"` -} - -// NewPluginMetaSpec creates a new PluginMetaSpec object. -func NewPluginMetaSpec() *PluginMetaSpec { - return &PluginMetaSpec{ - PluginJSON: *NewPluginMetaJSONData(), - } -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1InfoLogos struct { - Small string `json:"small"` - Large string `json:"large"` -} - -// NewPluginMetaV0alpha1InfoLogos creates a new PluginMetaV0alpha1InfoLogos object. -func NewPluginMetaV0alpha1InfoLogos() *PluginMetaV0alpha1InfoLogos { - return &PluginMetaV0alpha1InfoLogos{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1InfoAuthor struct { - Name *string `json:"name,omitempty"` - Email *string `json:"email,omitempty"` - Url *string `json:"url,omitempty"` -} - -// NewPluginMetaV0alpha1InfoAuthor creates a new PluginMetaV0alpha1InfoAuthor object. -func NewPluginMetaV0alpha1InfoAuthor() *PluginMetaV0alpha1InfoAuthor { - return &PluginMetaV0alpha1InfoAuthor{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1InfoLinks struct { - Name *string `json:"name,omitempty"` - Url *string `json:"url,omitempty"` -} - -// NewPluginMetaV0alpha1InfoLinks creates a new PluginMetaV0alpha1InfoLinks object. -func NewPluginMetaV0alpha1InfoLinks() *PluginMetaV0alpha1InfoLinks { - return &PluginMetaV0alpha1InfoLinks{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1InfoScreenshots struct { - Name *string `json:"name,omitempty"` - Path *string `json:"path,omitempty"` -} - -// NewPluginMetaV0alpha1InfoScreenshots creates a new PluginMetaV0alpha1InfoScreenshots object. -func NewPluginMetaV0alpha1InfoScreenshots() *PluginMetaV0alpha1InfoScreenshots { - return &PluginMetaV0alpha1InfoScreenshots{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1DependenciesPlugins struct { - Id string `json:"id"` - Type PluginMetaV0alpha1DependenciesPluginsType `json:"type"` - Name string `json:"name"` -} - -// NewPluginMetaV0alpha1DependenciesPlugins creates a new PluginMetaV0alpha1DependenciesPlugins object. -func NewPluginMetaV0alpha1DependenciesPlugins() *PluginMetaV0alpha1DependenciesPlugins { - return &PluginMetaV0alpha1DependenciesPlugins{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1DependenciesExtensions struct { - // +listType=set - ExposedComponents []string `json:"exposedComponents,omitempty"` -} - -// NewPluginMetaV0alpha1DependenciesExtensions creates a new PluginMetaV0alpha1DependenciesExtensions object. -func NewPluginMetaV0alpha1DependenciesExtensions() *PluginMetaV0alpha1DependenciesExtensions { - return &PluginMetaV0alpha1DependenciesExtensions{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1RouteTokenAuth struct { - Url *string `json:"url,omitempty"` - // +listType=set - Scopes []string `json:"scopes,omitempty"` - Params map[string]interface{} `json:"params,omitempty"` -} - -// NewPluginMetaV0alpha1RouteTokenAuth creates a new PluginMetaV0alpha1RouteTokenAuth object. -func NewPluginMetaV0alpha1RouteTokenAuth() *PluginMetaV0alpha1RouteTokenAuth { - return &PluginMetaV0alpha1RouteTokenAuth{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1RouteJwtTokenAuth struct { - Url *string `json:"url,omitempty"` - // +listType=set - Scopes []string `json:"scopes,omitempty"` - Params map[string]interface{} `json:"params,omitempty"` -} - -// NewPluginMetaV0alpha1RouteJwtTokenAuth creates a new PluginMetaV0alpha1RouteJwtTokenAuth object. -func NewPluginMetaV0alpha1RouteJwtTokenAuth() *PluginMetaV0alpha1RouteJwtTokenAuth { - return &PluginMetaV0alpha1RouteJwtTokenAuth{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1RouteUrlParams struct { - Name *string `json:"name,omitempty"` - Content *string `json:"content,omitempty"` -} - -// NewPluginMetaV0alpha1RouteUrlParams creates a new PluginMetaV0alpha1RouteUrlParams object. -func NewPluginMetaV0alpha1RouteUrlParams() *PluginMetaV0alpha1RouteUrlParams { - return &PluginMetaV0alpha1RouteUrlParams{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1IAMPermissions struct { - Action *string `json:"action,omitempty"` - Scope *string `json:"scope,omitempty"` -} - -// NewPluginMetaV0alpha1IAMPermissions creates a new PluginMetaV0alpha1IAMPermissions object. -func NewPluginMetaV0alpha1IAMPermissions() *PluginMetaV0alpha1IAMPermissions { - return &PluginMetaV0alpha1IAMPermissions{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1RoleRolePermissions struct { - Action *string `json:"action,omitempty"` - Scope *string `json:"scope,omitempty"` -} - -// NewPluginMetaV0alpha1RoleRolePermissions creates a new PluginMetaV0alpha1RoleRolePermissions object. -func NewPluginMetaV0alpha1RoleRolePermissions() *PluginMetaV0alpha1RoleRolePermissions { - return &PluginMetaV0alpha1RoleRolePermissions{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1RoleRole struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - // +listType=atomic - Permissions []PluginMetaV0alpha1RoleRolePermissions `json:"permissions,omitempty"` -} - -// NewPluginMetaV0alpha1RoleRole creates a new PluginMetaV0alpha1RoleRole object. -func NewPluginMetaV0alpha1RoleRole() *PluginMetaV0alpha1RoleRole { - return &PluginMetaV0alpha1RoleRole{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1ExtensionsAddedComponents struct { - // +listType=set - Targets []string `json:"targets"` - Title string `json:"title"` - Description *string `json:"description,omitempty"` -} - -// NewPluginMetaV0alpha1ExtensionsAddedComponents creates a new PluginMetaV0alpha1ExtensionsAddedComponents object. -func NewPluginMetaV0alpha1ExtensionsAddedComponents() *PluginMetaV0alpha1ExtensionsAddedComponents { - return &PluginMetaV0alpha1ExtensionsAddedComponents{ - Targets: []string{}, - } -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1ExtensionsAddedLinks struct { - // +listType=set - Targets []string `json:"targets"` - Title string `json:"title"` - Description *string `json:"description,omitempty"` -} - -// NewPluginMetaV0alpha1ExtensionsAddedLinks creates a new PluginMetaV0alpha1ExtensionsAddedLinks object. -func NewPluginMetaV0alpha1ExtensionsAddedLinks() *PluginMetaV0alpha1ExtensionsAddedLinks { - return &PluginMetaV0alpha1ExtensionsAddedLinks{ - Targets: []string{}, - } -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1ExtensionsExposedComponents struct { - Id string `json:"id"` - Title *string `json:"title,omitempty"` - Description *string `json:"description,omitempty"` -} - -// NewPluginMetaV0alpha1ExtensionsExposedComponents creates a new PluginMetaV0alpha1ExtensionsExposedComponents object. -func NewPluginMetaV0alpha1ExtensionsExposedComponents() *PluginMetaV0alpha1ExtensionsExposedComponents { - return &PluginMetaV0alpha1ExtensionsExposedComponents{} -} - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1ExtensionsExtensionPoints struct { - Id string `json:"id"` - Title *string `json:"title,omitempty"` - Description *string `json:"description,omitempty"` -} - -// NewPluginMetaV0alpha1ExtensionsExtensionPoints creates a new PluginMetaV0alpha1ExtensionsExtensionPoints object. -func NewPluginMetaV0alpha1ExtensionsExtensionPoints() *PluginMetaV0alpha1ExtensionsExtensionPoints { - return &PluginMetaV0alpha1ExtensionsExtensionPoints{} -} - -// +k8s:openapi-gen=true -type PluginMetaJSONDataType string - -const ( - PluginMetaJSONDataTypeApp PluginMetaJSONDataType = "app" - PluginMetaJSONDataTypeDatasource PluginMetaJSONDataType = "datasource" - PluginMetaJSONDataTypePanel PluginMetaJSONDataType = "panel" - PluginMetaJSONDataTypeRenderer PluginMetaJSONDataType = "renderer" -) - -// +k8s:openapi-gen=true -type PluginMetaJSONDataCategory string - -const ( - PluginMetaJSONDataCategoryTsdb PluginMetaJSONDataCategory = "tsdb" - PluginMetaJSONDataCategoryLogging PluginMetaJSONDataCategory = "logging" - PluginMetaJSONDataCategoryCloud PluginMetaJSONDataCategory = "cloud" - PluginMetaJSONDataCategoryTracing PluginMetaJSONDataCategory = "tracing" - PluginMetaJSONDataCategoryProfiling PluginMetaJSONDataCategory = "profiling" - PluginMetaJSONDataCategorySql PluginMetaJSONDataCategory = "sql" - PluginMetaJSONDataCategoryEnterprise PluginMetaJSONDataCategory = "enterprise" - PluginMetaJSONDataCategoryIot PluginMetaJSONDataCategory = "iot" - PluginMetaJSONDataCategoryOther PluginMetaJSONDataCategory = "other" -) - -// +k8s:openapi-gen=true -type PluginMetaJSONDataState string - -const ( - PluginMetaJSONDataStateAlpha PluginMetaJSONDataState = "alpha" - PluginMetaJSONDataStateBeta PluginMetaJSONDataState = "beta" -) - -// +k8s:openapi-gen=true -type PluginMetaIncludeType string - -const ( - PluginMetaIncludeTypeDashboard PluginMetaIncludeType = "dashboard" - PluginMetaIncludeTypePage PluginMetaIncludeType = "page" - PluginMetaIncludeTypePanel PluginMetaIncludeType = "panel" - PluginMetaIncludeTypeDatasource PluginMetaIncludeType = "datasource" -) - -// +k8s:openapi-gen=true -type PluginMetaIncludeRole string - -const ( - PluginMetaIncludeRoleAdmin PluginMetaIncludeRole = "Admin" - PluginMetaIncludeRoleEditor PluginMetaIncludeRole = "Editor" - PluginMetaIncludeRoleViewer PluginMetaIncludeRole = "Viewer" -) - -// +k8s:openapi-gen=true -type PluginMetaV0alpha1DependenciesPluginsType string - -const ( - PluginMetaV0alpha1DependenciesPluginsTypeApp PluginMetaV0alpha1DependenciesPluginsType = "app" - PluginMetaV0alpha1DependenciesPluginsTypeDatasource PluginMetaV0alpha1DependenciesPluginsType = "datasource" - PluginMetaV0alpha1DependenciesPluginsTypePanel PluginMetaV0alpha1DependenciesPluginsType = "panel" -) diff --git a/apps/plugins/pkg/apis/plugins_manifest.go b/apps/plugins/pkg/apis/plugins_manifest.go index e09c70244a7..0c52665e75d 100644 --- a/apps/plugins/pkg/apis/plugins_manifest.go +++ b/apps/plugins/pkg/apis/plugins_manifest.go @@ -20,12 +20,12 @@ import ( ) var ( - rawSchemaPluginv0alpha1 = []byte(`{"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"Plugin":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"class":{"enum":["core","external"],"type":"string"},"id":{"type":"string"},"url":{"type":"string"},"version":{"type":"string"}},"required":["id","version","class"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) - versionSchemaPluginv0alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaPluginv0alpha1, &versionSchemaPluginv0alpha1) - rawSchemaPluginMetav0alpha1 = []byte(`{"Dependencies":{"additionalProperties":false,"properties":{"extensions":{"additionalProperties":false,"properties":{"exposedComponents":{"description":"+listType=set","items":{"type":"string"},"type":"array"}},"type":"object"},"grafanaDependency":{"description":"Required field","type":"string"},"grafanaVersion":{"description":"Optional fields","type":"string"},"plugins":{"description":"+listType=set\n+listMapKey=id","items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"enum":["app","datasource","panel"],"type":"string"}},"required":["id","type","name"],"type":"object"},"type":"array"}},"required":["grafanaDependency"],"type":"object"},"EnterpriseFeatures":{"additionalProperties":false,"properties":{"healthDiagnosticsErrors":{"default":false,"description":"Allow additional properties","type":"boolean"}},"type":"object"},"Extensions":{"additionalProperties":false,"properties":{"addedComponents":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"targets":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"title":{"type":"string"}},"required":["targets","title"],"type":"object"},"type":"array"},"addedLinks":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"targets":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"title":{"type":"string"}},"required":["targets","title"],"type":"object"},"type":"array"},"exposedComponents":{"description":"+listType=set\n+listMapKey=id","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}},"required":["id"],"type":"object"},"type":"array"},"extensionPoints":{"description":"+listType=set\n+listMapKey=id","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}},"required":["id"],"type":"object"},"type":"array"}},"type":"object"},"IAM":{"additionalProperties":false,"properties":{"permissions":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"action":{"type":"string"},"scope":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"},"Include":{"additionalProperties":false,"properties":{"action":{"type":"string"},"addToNav":{"type":"boolean"},"component":{"type":"string"},"defaultNav":{"type":"boolean"},"icon":{"type":"string"},"name":{"type":"string"},"path":{"type":"string"},"role":{"enum":["Admin","Editor","Viewer"],"type":"string"},"type":{"enum":["dashboard","page","panel","datasource"],"type":"string"},"uid":{"type":"string"}},"type":"object"},"Info":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"description":"Optional fields","properties":{"email":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"description":{"type":"string"},"keywords":{"description":"Required fields\n+listType=set","items":{"type":"string"},"type":"array"},"links":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"type":"array"},"logos":{"additionalProperties":false,"properties":{"large":{"type":"string"},"small":{"type":"string"}},"required":["small","large"],"type":"object"},"screenshots":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"path":{"type":"string"}},"type":"object"},"type":"array"},"updated":{"type":"string"},"version":{"type":"string"}},"required":["keywords","logos","updated","version"],"type":"object"},"JSONData":{"additionalProperties":false,"description":"JSON configuration schema for Grafana plugins\nConverted from: https://github.com/grafana/grafana/blob/main/docs/sources/developers/plugins/plugin.schema.json","properties":{"alerting":{"description":"Optional fields","type":"boolean"},"annotations":{"type":"boolean"},"autoEnabled":{"type":"boolean"},"backend":{"type":"boolean"},"buildMode":{"type":"string"},"builtIn":{"type":"boolean"},"category":{"enum":["tsdb","logging","cloud","tracing","profiling","sql","enterprise","iot","other"],"type":"string"},"dependencies":{"$ref":"#/components/schemas/Dependencies","description":"Dependency information"},"enterpriseFeatures":{"$ref":"#/components/schemas/EnterpriseFeatures"},"executable":{"type":"string"},"extensions":{"$ref":"#/components/schemas/Extensions"},"hideFromList":{"type":"boolean"},"iam":{"$ref":"#/components/schemas/IAM"},"id":{"description":"Unique name of the plugin","type":"string"},"includes":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Include"},"type":"array"},"info":{"$ref":"#/components/schemas/Info","description":"Metadata for the plugin"},"logs":{"type":"boolean"},"metrics":{"type":"boolean"},"multiValueFilterOperators":{"type":"boolean"},"name":{"description":"Human-readable name of the plugin","type":"string"},"pascalName":{"type":"string"},"preload":{"type":"boolean"},"queryOptions":{"$ref":"#/components/schemas/QueryOptions"},"roles":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Role"},"type":"array"},"routes":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Route"},"type":"array"},"skipDataQuery":{"type":"boolean"},"state":{"enum":["alpha","beta"],"type":"string"},"streaming":{"type":"boolean"},"suggestions":{"type":"boolean"},"tracing":{"type":"boolean"},"type":{"description":"Plugin type","enum":["app","datasource","panel","renderer"],"type":"string"}},"required":["id","type","name","info","dependencies"],"type":"object"},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"PluginMeta":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"QueryOptions":{"additionalProperties":false,"properties":{"cacheTimeout":{"type":"boolean"},"maxDataPoints":{"type":"boolean"},"minInterval":{"type":"boolean"}},"type":"object"},"Role":{"additionalProperties":false,"properties":{"grants":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"role":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"action":{"type":"string"},"scope":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"}},"type":"object"},"Route":{"additionalProperties":false,"properties":{"body":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"headers":{"description":"+listType=atomic","items":{"type":"string"},"type":"array"},"jwtTokenAuth":{"additionalProperties":false,"properties":{"params":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"scopes":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"url":{"type":"string"}},"type":"object"},"method":{"type":"string"},"path":{"type":"string"},"reqAction":{"type":"string"},"reqRole":{"type":"string"},"reqSignedIn":{"type":"boolean"},"tokenAuth":{"additionalProperties":false,"properties":{"params":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"scopes":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"url":{"type":"string"}},"type":"object"},"url":{"type":"string"},"urlParams":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"content":{"type":"string"},"name":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"},"spec":{"additionalProperties":false,"properties":{"pluginJSON":{"$ref":"#/components/schemas/JSONData"}},"required":["pluginJSON"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) - versionSchemaPluginMetav0alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaPluginMetav0alpha1, &versionSchemaPluginMetav0alpha1) + rawSchemaPluginv0alpha1 = []byte(`{"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"Plugin":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"spec":{"additionalProperties":false,"properties":{"id":{"type":"string"},"url":{"type":"string"},"version":{"type":"string"}},"required":["id","version"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) + versionSchemaPluginv0alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaPluginv0alpha1, &versionSchemaPluginv0alpha1) + rawSchemaMetav0alpha1 = []byte(`{"Dependencies":{"additionalProperties":false,"properties":{"extensions":{"additionalProperties":false,"properties":{"exposedComponents":{"description":"+listType=set","items":{"type":"string"},"type":"array"}},"type":"object"},"grafanaDependency":{"description":"Required field","type":"string"},"grafanaVersion":{"description":"Optional fields","type":"string"},"plugins":{"description":"+listType=set\n+listMapKey=id","items":{"additionalProperties":false,"properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"enum":["app","datasource","panel"],"type":"string"}},"required":["id","type","name"],"type":"object"},"type":"array"}},"required":["grafanaDependency"],"type":"object"},"EnterpriseFeatures":{"additionalProperties":false,"properties":{"healthDiagnosticsErrors":{"default":false,"description":"Allow additional properties","type":"boolean"}},"type":"object"},"Extensions":{"additionalProperties":false,"properties":{"addedComponents":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"targets":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"title":{"type":"string"}},"required":["targets","title"],"type":"object"},"type":"array"},"addedFunctions":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"targets":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"title":{"type":"string"}},"required":["targets","title"],"type":"object"},"type":"array"},"addedLinks":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"targets":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"title":{"type":"string"}},"required":["targets","title"],"type":"object"},"type":"array"},"exposedComponents":{"description":"+listType=set\n+listMapKey=id","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}},"required":["id"],"type":"object"},"type":"array"},"extensionPoints":{"description":"+listType=set\n+listMapKey=id","items":{"additionalProperties":false,"properties":{"description":{"type":"string"},"id":{"type":"string"},"title":{"type":"string"}},"required":["id"],"type":"object"},"type":"array"}},"type":"object"},"IAM":{"additionalProperties":false,"properties":{"permissions":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"action":{"type":"string"},"scope":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"},"Include":{"additionalProperties":false,"properties":{"action":{"type":"string"},"addToNav":{"type":"boolean"},"component":{"type":"string"},"defaultNav":{"type":"boolean"},"icon":{"type":"string"},"name":{"type":"string"},"path":{"type":"string"},"role":{"enum":["Admin","Editor","Viewer","None"],"type":"string"},"type":{"enum":["dashboard","page","panel","datasource"],"type":"string"},"uid":{"type":"string"}},"type":"object"},"Info":{"additionalProperties":false,"properties":{"author":{"additionalProperties":false,"description":"Optional fields","properties":{"email":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"description":{"type":"string"},"keywords":{"description":"Required fields\n+listType=set","items":{"type":"string"},"type":"array"},"links":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"url":{"type":"string"}},"type":"object"},"type":"array"},"logos":{"additionalProperties":false,"properties":{"large":{"type":"string"},"small":{"type":"string"}},"required":["small","large"],"type":"object"},"screenshots":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"name":{"type":"string"},"path":{"type":"string"}},"type":"object"},"type":"array"},"updated":{"type":"string"},"version":{"type":"string"}},"required":["keywords","logos","updated","version"],"type":"object"},"JSONData":{"additionalProperties":false,"description":"JSON configuration schema for Grafana plugins\nConverted from: https://github.com/grafana/grafana/blob/main/docs/sources/developers/plugins/plugin.schema.json","properties":{"alerting":{"description":"Optional fields","type":"boolean"},"annotations":{"type":"boolean"},"autoEnabled":{"type":"boolean"},"backend":{"type":"boolean"},"buildMode":{"type":"string"},"builtIn":{"type":"boolean"},"category":{"enum":["tsdb","logging","cloud","tracing","profiling","sql","enterprise","iot","other"],"type":"string"},"dependencies":{"$ref":"#/components/schemas/Dependencies","description":"Dependency information"},"enterpriseFeatures":{"$ref":"#/components/schemas/EnterpriseFeatures"},"executable":{"type":"string"},"extensions":{"$ref":"#/components/schemas/Extensions"},"hideFromList":{"type":"boolean"},"iam":{"$ref":"#/components/schemas/IAM"},"id":{"description":"Unique name of the plugin","type":"string"},"includes":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Include"},"type":"array"},"info":{"$ref":"#/components/schemas/Info","description":"Metadata for the plugin"},"logs":{"type":"boolean"},"metrics":{"type":"boolean"},"multiValueFilterOperators":{"type":"boolean"},"name":{"description":"Human-readable name of the plugin","type":"string"},"pascalName":{"type":"string"},"preload":{"type":"boolean"},"queryOptions":{"$ref":"#/components/schemas/QueryOptions"},"roles":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Role"},"type":"array"},"routes":{"description":"+listType=atomic","items":{"$ref":"#/components/schemas/Route"},"type":"array"},"skipDataQuery":{"type":"boolean"},"state":{"enum":["alpha","beta"],"type":"string"},"streaming":{"type":"boolean"},"suggestions":{"type":"boolean"},"tracing":{"type":"boolean"},"type":{"description":"Plugin type","enum":["app","datasource","panel","renderer"],"type":"string"}},"required":["id","type","name","info","dependencies"],"type":"object"},"Meta":{"properties":{"spec":{"$ref":"#/components/schemas/spec"},"status":{"$ref":"#/components/schemas/status"}},"required":["spec"]},"OperatorState":{"additionalProperties":false,"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"details contains any extra information that is operator-specific","type":"object"},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"QueryOptions":{"additionalProperties":false,"properties":{"cacheTimeout":{"type":"boolean"},"maxDataPoints":{"type":"boolean"},"minInterval":{"type":"boolean"}},"type":"object"},"Role":{"additionalProperties":false,"properties":{"grants":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"role":{"additionalProperties":false,"properties":{"description":{"type":"string"},"name":{"type":"string"},"permissions":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"action":{"type":"string"},"scope":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"}},"type":"object"},"Route":{"additionalProperties":false,"properties":{"body":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"headers":{"description":"+listType=atomic","items":{"type":"string"},"type":"array"},"jwtTokenAuth":{"additionalProperties":false,"properties":{"params":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"scopes":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"url":{"type":"string"}},"type":"object"},"method":{"type":"string"},"path":{"type":"string"},"reqAction":{"type":"string"},"reqRole":{"type":"string"},"reqSignedIn":{"type":"boolean"},"tokenAuth":{"additionalProperties":false,"properties":{"params":{"additionalProperties":{"additionalProperties":{},"type":"object"},"type":"object"},"scopes":{"description":"+listType=set","items":{"type":"string"},"type":"array"},"url":{"type":"string"}},"type":"object"},"url":{"type":"string"},"urlParams":{"description":"+listType=atomic","items":{"additionalProperties":false,"properties":{"content":{"type":"string"},"name":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"},"spec":{"additionalProperties":false,"properties":{"angular":{"additionalProperties":false,"properties":{"detected":{"type":"boolean"}},"required":["detected"],"type":"object"},"baseURL":{"type":"string"},"children":{"description":"+listType=atomic","items":{"type":"string"},"type":"array"},"class":{"enum":["core","external"],"type":"string"},"module":{"additionalProperties":false,"properties":{"hash":{"type":"string"},"loadingStrategy":{"enum":["fetch","script"],"type":"string"},"path":{"type":"string"}},"required":["path"],"type":"object"},"pluginJson":{"$ref":"#/components/schemas/JSONData"},"signature":{"additionalProperties":false,"properties":{"org":{"type":"string"},"status":{"enum":["internal","valid","invalid","modified","unsigned"],"type":"string"},"type":{"enum":["grafana","commercial","community","private","private-glob"],"type":"string"}},"required":["status"],"type":"object"},"translations":{"additionalProperties":{"type":"string"},"type":"object"}},"required":["pluginJson","class"],"type":"object"},"status":{"additionalProperties":false,"properties":{"additionalFields":{"additionalProperties":{"additionalProperties":{},"type":"object"},"description":"additionalFields is reserved for future use","type":"object"},"operatorStates":{"additionalProperties":{"$ref":"#/components/schemas/OperatorState"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object"}}`) + versionSchemaMetav0alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaMetav0alpha1, &versionSchemaMetav0alpha1) ) var appManifestData = app.ManifestData{ @@ -46,11 +46,11 @@ var appManifestData = app.ManifestData{ }, { - Kind: "PluginMeta", - Plural: "PluginMetas", + Kind: "Meta", + Plural: "Metas", Scope: "Namespaced", Conversion: false, - Schema: &versionSchemaPluginMetav0alpha1, + Schema: &versionSchemaMetav0alpha1, }, }, Routes: app.ManifestVersionRoutes{ @@ -71,8 +71,8 @@ func RemoteManifest() app.Manifest { } var kindVersionToGoType = map[string]resource.Kind{ - "Plugin/v0alpha1": v0alpha1.PluginKind(), - "PluginMeta/v0alpha1": v0alpha1.PluginMetaKind(), + "Plugin/v0alpha1": v0alpha1.PluginKind(), + "Meta/v0alpha1": v0alpha1.MetaKind(), } // ManifestGoTypeAssociator returns the associated resource.Kind instance for a given Kind and Version, if one exists. diff --git a/apps/plugins/pkg/app/app.go b/apps/plugins/pkg/app/app.go index 3d17cc34221..c296bccd9e1 100644 --- a/apps/plugins/pkg/app/app.go +++ b/apps/plugins/pkg/app/app.go @@ -3,6 +3,7 @@ package app import ( "context" "fmt" + "sync" "github.com/grafana/grafana-app-sdk/app" "github.com/grafana/grafana-app-sdk/k8s" @@ -16,7 +17,6 @@ import ( restclient "k8s.io/client-go/rest" "k8s.io/klog/v2" - authlib "github.com/grafana/authlib/types" pluginsappapis "github.com/grafana/grafana/apps/plugins/pkg/apis" pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1" "github.com/grafana/grafana/apps/plugins/pkg/app/meta" @@ -43,7 +43,7 @@ func New(cfg app.Config) (app.App, error) { Kind: pluginsv0alpha1.PluginKind(), }, { - Kind: pluginsv0alpha1.PluginMetaKind(), + Kind: pluginsv0alpha1.MetaKind(), }, }, } @@ -69,6 +69,7 @@ type PluginAppConfig struct { } func ProvideAppInstaller( + authorizer authorizer.Authorizer, metaProviderManager *meta.ProviderManager, ) (*PluginAppInstaller, error) { specificConfig := &PluginAppConfig{ @@ -87,31 +88,30 @@ func ProvideAppInstaller( appInstaller := &PluginAppInstaller{ AppInstaller: defaultInstaller, + authorizer: authorizer, metaManager: metaProviderManager, ready: make(chan struct{}), } return appInstaller, nil } -func (p *PluginAppInstaller) WithAccessChecker(access authlib.AccessChecker) *PluginAppInstaller { - p.access = access - return p -} - type PluginAppInstaller struct { appsdkapiserver.AppInstaller metaManager *meta.ProviderManager - access authlib.AccessChecker + authorizer authorizer.Authorizer // restConfig is set during InitializeApp and used by the client factory restConfig *restclient.Config ready chan struct{} + readyOnce sync.Once } func (p *PluginAppInstaller) InitializeApp(restConfig restclient.Config) error { if p.restConfig == nil { p.restConfig = &restConfig - close(p.ready) + p.readyOnce.Do(func() { + close(p.ready) + }) } return p.AppInstaller.InitializeApp(restConfig) } @@ -137,9 +137,9 @@ func (p *PluginAppInstaller) InstallAPIs( return client, nil } - pluginMetaGVR := pluginsv0alpha1.PluginMetaKind().GroupVersionResource() + pluginMetaGVR := pluginsv0alpha1.MetaKind().GroupVersionResource() replacedStorage := map[schema.GroupVersionResource]rest.Storage{ - pluginMetaGVR: NewPluginMetaStorage(p.metaManager, clientFactory), + pluginMetaGVR: NewMetaStorage(p.metaManager, clientFactory), } wrappedServer := &customStorageWrapper{ wrapped: server, @@ -149,34 +149,5 @@ func (p *PluginAppInstaller) InstallAPIs( } func (p *PluginAppInstaller) GetAuthorizer() authorizer.Authorizer { - if p.access == nil { - return nil - } - - return authorizer.AuthorizerFunc( - func(ctx context.Context, a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { - info, ok := authlib.AuthInfoFrom(ctx) - if !ok { - return authorizer.DecisionDeny, "failed to get auth info", nil - } - - res, err := p.access.Check(ctx, info, authlib.CheckRequest{ - Verb: a.GetVerb(), - Group: a.GetAPIGroup(), - Resource: a.GetResource(), - Name: a.GetName(), - Namespace: a.GetNamespace(), - Subresource: a.GetSubresource(), - Path: a.GetPath(), - }, "") - if err != nil { - return authorizer.DecisionDeny, "failed to perform authorization", err - } - - if !res.Allowed { - return authorizer.DecisionDeny, "permission denied", nil - } - - return authorizer.DecisionAllow, "", nil - }) + return p.authorizer } diff --git a/apps/plugins/pkg/app/authorizer.go b/apps/plugins/pkg/app/authorizer.go deleted file mode 100644 index b6a800694f7..00000000000 --- a/apps/plugins/pkg/app/authorizer.go +++ /dev/null @@ -1,32 +0,0 @@ -package app - -import ( - "context" - - "k8s.io/apiserver/pkg/authorization/authorizer" - - "github.com/grafana/grafana/pkg/apimachinery/identity" -) - -func GetAuthorizer() authorizer.Authorizer { - return authorizer.AuthorizerFunc(func( - ctx context.Context, attr authorizer.Attributes, - ) (authorized authorizer.Decision, reason string, err error) { - if !attr.IsResourceRequest() { - return authorizer.DecisionNoOpinion, "", nil - } - - // require a user - u, err := identity.GetRequester(ctx) - if err != nil { - return authorizer.DecisionDeny, "valid user is required", err - } - - // check if is admin - if u.HasRole(identity.RoleAdmin) { - return authorizer.DecisionAllow, "", nil - } - - return authorizer.DecisionDeny, "forbidden", nil - }) -} diff --git a/apps/plugins/pkg/app/install/registrar.go b/apps/plugins/pkg/app/install/registrar.go index 3977fd88cf0..a900db1a68d 100644 --- a/apps/plugins/pkg/app/install/registrar.go +++ b/apps/plugins/pkg/app/install/registrar.go @@ -15,16 +15,6 @@ const ( PluginInstallSourceAnnotation = "plugins.grafana.app/install-source" ) -// Class represents the plugin class type in an unversioned internal format. -// This intentionally duplicates the versioned API type (PluginInstallSpecClass) to decouple -// internal code from API version changes, making it easier to support multiple API versions. -type Class = string - -const ( - ClassCore Class = "core" - ClassExternal Class = "external" -) - type Source = string const ( @@ -36,7 +26,6 @@ type PluginInstall struct { ID string Version string URL string - Class Class Source Source } @@ -57,7 +46,6 @@ func (p *PluginInstall) ToPluginInstallV0Alpha1(namespace string) *pluginsv0alph Id: p.ID, Version: p.Version, Url: url, - Class: pluginsv0alpha1.PluginSpecClass(p.Class), }, } } @@ -70,9 +58,6 @@ func (p *PluginInstall) ShouldUpdate(existing *pluginsv0alpha1.Plugin) bool { if existing.Spec.Version != update.Spec.Version { return true } - if existing.Spec.Class != update.Spec.Class { - return true // this should never really happen - } if !equalStringPointers(existing.Spec.Url, update.Spec.Url) { return true } diff --git a/apps/plugins/pkg/app/install/registrar_test.go b/apps/plugins/pkg/app/install/registrar_test.go index f1e0adbc508..6961acb98f8 100644 --- a/apps/plugins/pkg/app/install/registrar_test.go +++ b/apps/plugins/pkg/app/install/registrar_test.go @@ -26,14 +26,12 @@ func TestPluginInstall_ShouldUpdate(t *testing.T) { Spec: pluginsv0alpha1.PluginSpec{ Id: "plugin-1", Version: "1.0.0", - Class: pluginsv0alpha1.PluginSpecClass(ClassExternal), }, } baseInstall := PluginInstall{ ID: "plugin-1", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, } @@ -54,13 +52,6 @@ func TestPluginInstall_ShouldUpdate(t *testing.T) { }, expectUpdate: true, }, - { - name: "class differs", - modifyInstall: func(pi *PluginInstall) { - pi.Class = ClassCore - }, - expectUpdate: true, - }, { name: "url differs", modifyInstall: func(pi *PluginInstall) { @@ -109,7 +100,6 @@ func TestInstallRegistrar_Register(t *testing.T) { install: &PluginInstall{ ID: "plugin-1", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, existingErr: errorsK8s.NewNotFound(pluginGroupResource(), "plugin-1"), @@ -120,7 +110,6 @@ func TestInstallRegistrar_Register(t *testing.T) { install: &PluginInstall{ ID: "plugin-1", Version: "2.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, existing: &pluginsv0alpha1.Plugin{ @@ -135,7 +124,6 @@ func TestInstallRegistrar_Register(t *testing.T) { Spec: pluginsv0alpha1.PluginSpec{ Id: "plugin-1", Version: "1.0.0", - Class: pluginsv0alpha1.PluginSpecClass(ClassExternal), }, }, expectedUpdates: 1, @@ -145,7 +133,6 @@ func TestInstallRegistrar_Register(t *testing.T) { install: &PluginInstall{ ID: "plugin-1", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, existing: &pluginsv0alpha1.Plugin{ @@ -160,7 +147,6 @@ func TestInstallRegistrar_Register(t *testing.T) { Spec: pluginsv0alpha1.PluginSpec{ Id: "plugin-1", Version: "1.0.0", - Class: pluginsv0alpha1.PluginSpecClass(ClassExternal), }, }, }, @@ -169,7 +155,6 @@ func TestInstallRegistrar_Register(t *testing.T) { install: &PluginInstall{ ID: "plugin-err", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, existingErr: errorsK8s.NewInternalError(errors.New("boom")), @@ -410,7 +395,6 @@ func TestPluginInstall_ToPluginInstallV0Alpha1(t *testing.T) { install: PluginInstall{ ID: "plugin-1", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, namespace: "org-1", @@ -424,7 +408,6 @@ func TestPluginInstall_ToPluginInstallV0Alpha1(t *testing.T) { ID: "plugin-1", Version: "1.0.0", URL: "https://example.com/plugin.zip", - Class: ClassExternal, Source: SourcePluginStore, }, namespace: "org-1", @@ -433,25 +416,11 @@ func TestPluginInstall_ToPluginInstallV0Alpha1(t *testing.T) { require.Equal(t, "https://example.com/plugin.zip", *p.Spec.Url) }, }, - { - name: "core class is mapped correctly", - install: PluginInstall{ - ID: "plugin-core", - Version: "2.0.0", - Class: ClassCore, - Source: SourcePluginStore, - }, - namespace: "org-2", - validate: func(t *testing.T, p *pluginsv0alpha1.Plugin) { - require.Equal(t, pluginsv0alpha1.PluginSpecClass(ClassCore), p.Spec.Class) - }, - }, { name: "source annotation is set correctly", install: PluginInstall{ ID: "plugin-1", Version: "1.0.0", - Class: ClassExternal, Source: SourceUnknown, }, namespace: "org-1", @@ -464,7 +433,6 @@ func TestPluginInstall_ToPluginInstallV0Alpha1(t *testing.T) { install: PluginInstall{ ID: "my-plugin", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, namespace: "my-namespace", @@ -556,7 +524,6 @@ func TestPluginInstall_ShouldUpdate_URLTransitions(t *testing.T) { ID: "plugin-1", Version: "1.0.0", URL: newURL, - Class: ClassExternal, Source: SourcePluginStore, }, existingURL: nil, @@ -568,7 +535,6 @@ func TestPluginInstall_ShouldUpdate_URLTransitions(t *testing.T) { ID: "plugin-1", Version: "1.0.0", URL: "", - Class: ClassExternal, Source: SourcePluginStore, }, existingURL: &existingURL, @@ -580,7 +546,6 @@ func TestPluginInstall_ShouldUpdate_URLTransitions(t *testing.T) { ID: "plugin-1", Version: "1.0.0", URL: "", - Class: ClassExternal, Source: SourcePluginStore, }, existingURL: nil, @@ -592,7 +557,6 @@ func TestPluginInstall_ShouldUpdate_URLTransitions(t *testing.T) { ID: "plugin-1", Version: "1.0.0", URL: existingURL, - Class: ClassExternal, Source: SourcePluginStore, }, existingURL: &existingURL, @@ -614,7 +578,6 @@ func TestPluginInstall_ShouldUpdate_URLTransitions(t *testing.T) { Id: "plugin-1", Version: "1.0.0", Url: tt.existingURL, - Class: pluginsv0alpha1.PluginSpecClass(ClassExternal), }, } @@ -670,7 +633,6 @@ func TestInstallRegistrar_Register_ErrorCases(t *testing.T) { install: &PluginInstall{ ID: "plugin-1", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, setupClient: func(fc *fakePluginInstallClient) { @@ -688,7 +650,6 @@ func TestInstallRegistrar_Register_ErrorCases(t *testing.T) { install: &PluginInstall{ ID: "plugin-1", Version: "2.0.0", - Class: ClassExternal, Source: SourcePluginStore, }, setupClient: func(fc *fakePluginInstallClient) { @@ -705,7 +666,6 @@ func TestInstallRegistrar_Register_ErrorCases(t *testing.T) { Spec: pluginsv0alpha1.PluginSpec{ Id: "plugin-1", Version: "1.0.0", - Class: pluginsv0alpha1.PluginSpecClass(ClassExternal), }, }, nil } @@ -876,7 +836,6 @@ func TestInstallRegistrar_GetClientError(t *testing.T) { install := &PluginInstall{ ID: "plugin-1", Version: "1.0.0", - Class: ClassExternal, Source: SourcePluginStore, } diff --git a/apps/plugins/pkg/app/meta/catalog.go b/apps/plugins/pkg/app/meta/catalog.go new file mode 100644 index 00000000000..481db9b5947 --- /dev/null +++ b/apps/plugins/pkg/app/meta/catalog.go @@ -0,0 +1,93 @@ +package meta + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/url" + "path" + "time" + + "github.com/grafana/grafana-app-sdk/logging" +) + +const ( + defaultCatalogTTL = 1 * time.Hour +) + +// CatalogProvider retrieves plugin metadata from the grafana.com API. +type CatalogProvider struct { + httpClient *http.Client + grafanaComAPIURL string + log logging.Logger + ttl time.Duration +} + +// NewCatalogProvider creates a new CatalogProvider that fetches metadata from grafana.com. +func NewCatalogProvider(grafanaComAPIURL string) *CatalogProvider { + return NewCatalogProviderWithTTL(grafanaComAPIURL, defaultCatalogTTL) +} + +// NewCatalogProviderWithTTL creates a new CatalogProvider with a custom TTL. +func NewCatalogProviderWithTTL(grafanaComAPIURL string, ttl time.Duration) *CatalogProvider { + if grafanaComAPIURL == "" { + grafanaComAPIURL = "https://grafana.com/api/plugins" + } + + return &CatalogProvider{ + httpClient: &http.Client{ + Timeout: 10 * time.Second, + }, + grafanaComAPIURL: grafanaComAPIURL, + log: logging.DefaultLogger, + ttl: ttl, + } +} + +// GetMeta fetches plugin metadata from grafana.com API endpoint: +// GET /api/plugins/{pluginId}/versions/{version} +func (p *CatalogProvider) GetMeta(ctx context.Context, pluginID, version string) (*Result, error) { + u, err := url.Parse(p.grafanaComAPIURL) + if err != nil { + return nil, fmt.Errorf("invalid grafana.com API URL: %w", err) + } + + u.Path = path.Join(u.Path, pluginID, "versions", version) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) + if err != nil { + return nil, fmt.Errorf("failed to create request: %w", err) + } + + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", "grafana-plugins-app") + + resp, err := p.httpClient.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to fetch plugin metadata: %w", err) + } + defer func() { + if err = resp.Body.Close(); err != nil { + p.log.Warn("Failed to close response body", "error", err) + } + }() + + if resp.StatusCode == http.StatusNotFound { + return nil, ErrMetaNotFound + } + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected status code %d from grafana.com API", resp.StatusCode) + } + + var gcomMeta grafanaComPluginVersionMeta + if err = json.NewDecoder(resp.Body).Decode(&gcomMeta); err != nil { + return nil, fmt.Errorf("failed to decode response: %w", err) + } + + metaSpec := grafanaComPluginVersionMetaToMetaSpec(gcomMeta) + return &Result{ + Meta: metaSpec, + TTL: p.ttl, + }, nil +} diff --git a/apps/plugins/pkg/app/meta/cloud_test.go b/apps/plugins/pkg/app/meta/catalog_test.go similarity index 78% rename from apps/plugins/pkg/app/meta/cloud_test.go rename to apps/plugins/pkg/app/meta/catalog_test.go index bef2d1a5041..1dea816e002 100644 --- a/apps/plugins/pkg/app/meta/cloud_test.go +++ b/apps/plugins/pkg/app/meta/catalog_test.go @@ -15,14 +15,14 @@ import ( pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1" ) -func TestCloudProvider_GetMeta(t *testing.T) { +func TestCatalogProvider_GetMeta(t *testing.T) { ctx := context.Background() t.Run("successfully fetches plugin metadata", func(t *testing.T) { - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ + expectedMeta := pluginsv0alpha1.MetaJSONData{ Id: "test-plugin", Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -44,13 +44,13 @@ func TestCloudProvider_GetMeta(t *testing.T) { })) defer server.Close() - provider := NewCloudProvider(server.URL + "/api/plugins") + provider := NewCatalogProvider(server.URL + "/api/plugins") result, err := provider.GetMeta(ctx, "test-plugin", "1.0.0") require.NoError(t, err) require.NotNil(t, result) - assert.Equal(t, expectedMeta, result.Meta) - assert.Equal(t, defaultCloudTTL, result.TTL) + assert.Equal(t, expectedMeta, result.Meta.PluginJson) + assert.Equal(t, defaultCatalogTTL, result.TTL) }) t.Run("returns ErrMetaNotFound for 404 status", func(t *testing.T) { @@ -59,7 +59,7 @@ func TestCloudProvider_GetMeta(t *testing.T) { })) defer server.Close() - provider := NewCloudProvider(server.URL + "/api/plugins") + provider := NewCatalogProvider(server.URL + "/api/plugins") result, err := provider.GetMeta(ctx, "nonexistent-plugin", "1.0.0") assert.Error(t, err) @@ -73,7 +73,7 @@ func TestCloudProvider_GetMeta(t *testing.T) { })) defer server.Close() - provider := NewCloudProvider(server.URL + "/api/plugins") + provider := NewCatalogProvider(server.URL + "/api/plugins") result, err := provider.GetMeta(ctx, "test-plugin", "1.0.0") assert.Error(t, err) @@ -89,7 +89,7 @@ func TestCloudProvider_GetMeta(t *testing.T) { })) defer server.Close() - provider := NewCloudProvider(server.URL + "/api/plugins") + provider := NewCatalogProvider(server.URL + "/api/plugins") result, err := provider.GetMeta(ctx, "test-plugin", "1.0.0") assert.Error(t, err) @@ -98,7 +98,7 @@ func TestCloudProvider_GetMeta(t *testing.T) { }) t.Run("returns error for invalid API URL", func(t *testing.T) { - provider := NewCloudProvider("://invalid-url") + provider := NewCatalogProvider("://invalid-url") result, err := provider.GetMeta(ctx, "test-plugin", "1.0.0") assert.Error(t, err) @@ -108,10 +108,10 @@ func TestCloudProvider_GetMeta(t *testing.T) { t.Run("uses custom TTL when provided", func(t *testing.T) { customTTL := 2 * time.Hour - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ + expectedMeta := pluginsv0alpha1.MetaJSONData{ Id: "test-plugin", Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, } server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -127,7 +127,7 @@ func TestCloudProvider_GetMeta(t *testing.T) { })) defer server.Close() - provider := NewCloudProviderWithTTL(server.URL+"/api/plugins", customTTL) + provider := NewCatalogProviderWithTTL(server.URL+"/api/plugins", customTTL) result, err := provider.GetMeta(ctx, "test-plugin", "1.0.0") require.NoError(t, err) @@ -145,7 +145,7 @@ func TestCloudProvider_GetMeta(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) cancel() - provider := NewCloudProvider(server.URL + "/api/plugins") + provider := NewCatalogProvider(server.URL + "/api/plugins") result, err := provider.GetMeta(ctx, "test-plugin", "1.0.0") assert.Error(t, err) @@ -153,34 +153,34 @@ func TestCloudProvider_GetMeta(t *testing.T) { }) } -func TestNewCloudProvider(t *testing.T) { +func TestNewCatalogProvider(t *testing.T) { t.Run("creates provider with default TTL", func(t *testing.T) { - provider := NewCloudProvider("https://grafana.com/api/plugins") - assert.Equal(t, defaultCloudTTL, provider.ttl) + provider := NewCatalogProvider("https://grafana.com/api/plugins") + assert.Equal(t, defaultCatalogTTL, provider.ttl) assert.NotNil(t, provider.httpClient) assert.Equal(t, "https://grafana.com/api/plugins", provider.grafanaComAPIURL) }) t.Run("uses default URL when empty", func(t *testing.T) { - provider := NewCloudProvider("") + provider := NewCatalogProvider("") assert.Equal(t, "https://grafana.com/api/plugins", provider.grafanaComAPIURL) }) } -func TestNewCloudProviderWithTTL(t *testing.T) { +func TestNewCatalogProviderWithTTL(t *testing.T) { t.Run("creates provider with custom TTL", func(t *testing.T) { customTTL := 2 * time.Hour - provider := NewCloudProviderWithTTL("https://grafana.com/api/plugins", customTTL) + provider := NewCatalogProviderWithTTL("https://grafana.com/api/plugins", customTTL) assert.Equal(t, customTTL, provider.ttl) }) t.Run("accepts zero TTL", func(t *testing.T) { - provider := NewCloudProviderWithTTL("https://grafana.com/api/plugins", 0) + provider := NewCatalogProviderWithTTL("https://grafana.com/api/plugins", 0) assert.Equal(t, time.Duration(0), provider.ttl) }) t.Run("uses default URL when empty", func(t *testing.T) { - provider := NewCloudProviderWithTTL("", defaultCloudTTL) + provider := NewCatalogProviderWithTTL("", defaultCatalogTTL) assert.Equal(t, "https://grafana.com/api/plugins", provider.grafanaComAPIURL) }) } diff --git a/apps/plugins/pkg/app/meta/cloud.go b/apps/plugins/pkg/app/meta/cloud.go deleted file mode 100644 index f49445d093a..00000000000 --- a/apps/plugins/pkg/app/meta/cloud.go +++ /dev/null @@ -1,131 +0,0 @@ -package meta - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/url" - "path" - "time" - - "github.com/grafana/grafana-app-sdk/logging" - - pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1" -) - -const ( - defaultCloudTTL = 1 * time.Hour -) - -// CloudProvider retrieves plugin metadata from the grafana.com API. -type CloudProvider struct { - httpClient *http.Client - grafanaComAPIURL string - log logging.Logger - ttl time.Duration -} - -// NewCloudProvider creates a new CloudProvider that fetches metadata from grafana.com. -func NewCloudProvider(grafanaComAPIURL string) *CloudProvider { - return NewCloudProviderWithTTL(grafanaComAPIURL, defaultCloudTTL) -} - -// NewCloudProviderWithTTL creates a new CloudProvider with a custom TTL. -func NewCloudProviderWithTTL(grafanaComAPIURL string, ttl time.Duration) *CloudProvider { - if grafanaComAPIURL == "" { - grafanaComAPIURL = "https://grafana.com/api/plugins" - } - - return &CloudProvider{ - httpClient: &http.Client{ - Timeout: 10 * time.Second, - }, - grafanaComAPIURL: grafanaComAPIURL, - log: logging.DefaultLogger, - ttl: ttl, - } -} - -// GetMeta fetches plugin metadata from grafana.com API endpoint: -// GET /api/plugins/{pluginId}/versions/{version} -func (p *CloudProvider) GetMeta(ctx context.Context, pluginID, version string) (*Result, error) { - u, err := url.Parse(p.grafanaComAPIURL) - if err != nil { - return nil, fmt.Errorf("invalid grafana.com API URL: %w", err) - } - - u.Path = path.Join(u.Path, pluginID, "versions", version) - req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) - if err != nil { - return nil, fmt.Errorf("failed to create request: %w", err) - } - - req.Header.Set("Accept", "application/json") - req.Header.Set("User-Agent", "grafana-plugins-app") - - resp, err := p.httpClient.Do(req) - if err != nil { - return nil, fmt.Errorf("failed to fetch plugin metadata: %w", err) - } - defer func() { - if err = resp.Body.Close(); err != nil { - p.log.Warn("Failed to close response body", "error", err) - } - }() - - if resp.StatusCode == http.StatusNotFound { - return nil, ErrMetaNotFound - } - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected status code %d from grafana.com API", resp.StatusCode) - } - - var gcomMeta grafanaComPluginVersionMeta - if err = json.NewDecoder(resp.Body).Decode(&gcomMeta); err != nil { - return nil, fmt.Errorf("failed to decode response: %w", err) - } - - return &Result{ - Meta: gcomMeta.JSON, - TTL: p.ttl, - }, nil -} - -// grafanaComPluginVersionMeta represents the response from grafana.com API -// GET /api/plugins/{pluginId}/versions/{version} -type grafanaComPluginVersionMeta struct { - PluginID string `json:"pluginSlug"` - Version string `json:"version"` - URL string `json:"url"` - Commit string `json:"commit"` - Description string `json:"description"` - Keywords []string `json:"keywords"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - JSON pluginsv0alpha1.PluginMetaJSONData `json:"json"` - Readme string `json:"readme"` - Downloads int `json:"downloads"` - Verified bool `json:"verified"` - Status string `json:"status"` - StatusContext string `json:"statusContext"` - DownloadSlug string `json:"downloadSlug"` - SignatureType string `json:"signatureType"` - SignedByOrg string `json:"signedByOrg"` - SignedByOrgName string `json:"signedByOrgName"` - Packages struct { - Any struct { - Md5 string `json:"md5"` - Sha256 string `json:"sha256"` - PackageName string `json:"packageName"` - DownloadURL string `json:"downloadUrl"` - } `json:"any"` - } `json:"packages"` - Links []struct { - Rel string `json:"rel"` - Href string `json:"href"` - } `json:"links"` - AngularDetected bool `json:"angularDetected"` - Scopes []string `json:"scopes"` -} diff --git a/apps/plugins/pkg/app/meta/converter.go b/apps/plugins/pkg/app/meta/converter.go new file mode 100644 index 00000000000..b8c0c4371d7 --- /dev/null +++ b/apps/plugins/pkg/app/meta/converter.go @@ -0,0 +1,762 @@ +package meta + +import ( + "encoding/json" + "time" + + pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1" + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" +) + +// jsonDataToMetaJSONData converts a plugins.JSONData to a pluginsv0alpha1.MetaJSONData. +// nolint:gocyclo +func jsonDataToMetaJSONData(jsonData plugins.JSONData) pluginsv0alpha1.MetaJSONData { + meta := pluginsv0alpha1.MetaJSONData{ + Id: jsonData.ID, + Name: jsonData.Name, + } + + // Map plugin type + switch jsonData.Type { + case plugins.TypeApp: + meta.Type = pluginsv0alpha1.MetaJSONDataTypeApp + case plugins.TypeDataSource: + meta.Type = pluginsv0alpha1.MetaJSONDataTypeDatasource + case plugins.TypePanel: + meta.Type = pluginsv0alpha1.MetaJSONDataTypePanel + case plugins.TypeRenderer: + meta.Type = pluginsv0alpha1.MetaJSONDataTypeRenderer + } + + // Map Info + meta.Info = pluginsv0alpha1.MetaInfo{ + Keywords: jsonData.Info.Keywords, + Logos: pluginsv0alpha1.MetaV0alpha1InfoLogos{ + Small: jsonData.Info.Logos.Small, + Large: jsonData.Info.Logos.Large, + }, + Updated: jsonData.Info.Updated, + Version: jsonData.Info.Version, + } + + if jsonData.Info.Description != "" { + meta.Info.Description = &jsonData.Info.Description + } + + if jsonData.Info.Author.Name != "" || jsonData.Info.Author.URL != "" { + author := &pluginsv0alpha1.MetaV0alpha1InfoAuthor{} + if jsonData.Info.Author.Name != "" { + author.Name = &jsonData.Info.Author.Name + } + if jsonData.Info.Author.URL != "" { + author.Url = &jsonData.Info.Author.URL + } + meta.Info.Author = author + } + + if len(jsonData.Info.Links) > 0 { + meta.Info.Links = make([]pluginsv0alpha1.MetaV0alpha1InfoLinks, 0, len(jsonData.Info.Links)) + for _, link := range jsonData.Info.Links { + v0Link := pluginsv0alpha1.MetaV0alpha1InfoLinks{} + if link.Name != "" { + v0Link.Name = &link.Name + } + if link.URL != "" { + v0Link.Url = &link.URL + } + meta.Info.Links = append(meta.Info.Links, v0Link) + } + } + + if len(jsonData.Info.Screenshots) > 0 { + meta.Info.Screenshots = make([]pluginsv0alpha1.MetaV0alpha1InfoScreenshots, 0, len(jsonData.Info.Screenshots)) + for _, screenshot := range jsonData.Info.Screenshots { + v0Screenshot := pluginsv0alpha1.MetaV0alpha1InfoScreenshots{} + if screenshot.Name != "" { + v0Screenshot.Name = &screenshot.Name + } + if screenshot.Path != "" { + v0Screenshot.Path = &screenshot.Path + } + meta.Info.Screenshots = append(meta.Info.Screenshots, v0Screenshot) + } + } + + // Map Dependencies + meta.Dependencies = pluginsv0alpha1.MetaDependencies{ + GrafanaDependency: jsonData.Dependencies.GrafanaDependency, + } + + if jsonData.Dependencies.GrafanaVersion != "" { + meta.Dependencies.GrafanaVersion = &jsonData.Dependencies.GrafanaVersion + } + + if len(jsonData.Dependencies.Plugins) > 0 { + meta.Dependencies.Plugins = make([]pluginsv0alpha1.MetaV0alpha1DependenciesPlugins, 0, len(jsonData.Dependencies.Plugins)) + for _, dep := range jsonData.Dependencies.Plugins { + var depType pluginsv0alpha1.MetaV0alpha1DependenciesPluginsType + switch dep.Type { + case "app": + depType = pluginsv0alpha1.MetaV0alpha1DependenciesPluginsTypeApp + case "datasource": + depType = pluginsv0alpha1.MetaV0alpha1DependenciesPluginsTypeDatasource + case "panel": + depType = pluginsv0alpha1.MetaV0alpha1DependenciesPluginsTypePanel + } + meta.Dependencies.Plugins = append(meta.Dependencies.Plugins, pluginsv0alpha1.MetaV0alpha1DependenciesPlugins{ + Id: dep.ID, + Type: depType, + Name: dep.Name, + }) + } + } + + if len(jsonData.Dependencies.Extensions.ExposedComponents) > 0 { + meta.Dependencies.Extensions = &pluginsv0alpha1.MetaV0alpha1DependenciesExtensions{ + ExposedComponents: jsonData.Dependencies.Extensions.ExposedComponents, + } + } + + // Map optional boolean fields + if jsonData.Alerting { + meta.Alerting = &jsonData.Alerting + } + if jsonData.Annotations { + meta.Annotations = &jsonData.Annotations + } + if jsonData.AutoEnabled { + meta.AutoEnabled = &jsonData.AutoEnabled + } + if jsonData.Backend { + meta.Backend = &jsonData.Backend + } + if jsonData.BuiltIn { + meta.BuiltIn = &jsonData.BuiltIn + } + if jsonData.HideFromList { + meta.HideFromList = &jsonData.HideFromList + } + if jsonData.Logs { + meta.Logs = &jsonData.Logs + } + if jsonData.Metrics { + meta.Metrics = &jsonData.Metrics + } + if jsonData.MultiValueFilterOperators { + meta.MultiValueFilterOperators = &jsonData.MultiValueFilterOperators + } + if jsonData.Preload { + meta.Preload = &jsonData.Preload + } + if jsonData.SkipDataQuery { + meta.SkipDataQuery = &jsonData.SkipDataQuery + } + if jsonData.Streaming { + meta.Streaming = &jsonData.Streaming + } + if jsonData.Tracing { + meta.Tracing = &jsonData.Tracing + } + + // Map category + if jsonData.Category != "" { + var category pluginsv0alpha1.MetaJSONDataCategory + switch jsonData.Category { + case "tsdb": + category = pluginsv0alpha1.MetaJSONDataCategoryTsdb + case "logging": + category = pluginsv0alpha1.MetaJSONDataCategoryLogging + case "cloud": + category = pluginsv0alpha1.MetaJSONDataCategoryCloud + case "tracing": + category = pluginsv0alpha1.MetaJSONDataCategoryTracing + case "profiling": + category = pluginsv0alpha1.MetaJSONDataCategoryProfiling + case "sql": + category = pluginsv0alpha1.MetaJSONDataCategorySql + case "enterprise": + category = pluginsv0alpha1.MetaJSONDataCategoryEnterprise + case "iot": + category = pluginsv0alpha1.MetaJSONDataCategoryIot + case "other": + category = pluginsv0alpha1.MetaJSONDataCategoryOther + default: + category = pluginsv0alpha1.MetaJSONDataCategoryOther + } + meta.Category = &category + } + + // Map state + if jsonData.State != "" { + var state pluginsv0alpha1.MetaJSONDataState + switch jsonData.State { + case plugins.ReleaseStateAlpha: + state = pluginsv0alpha1.MetaJSONDataStateAlpha + case plugins.ReleaseStateBeta: + state = pluginsv0alpha1.MetaJSONDataStateBeta + default: + } + if state != "" { + meta.State = &state + } + } + + // Map executable + if jsonData.Executable != "" { + meta.Executable = &jsonData.Executable + } + + // Map QueryOptions + if len(jsonData.QueryOptions) > 0 { + queryOptions := &pluginsv0alpha1.MetaQueryOptions{} + if val, ok := jsonData.QueryOptions["maxDataPoints"]; ok { + queryOptions.MaxDataPoints = &val + } + if val, ok := jsonData.QueryOptions["minInterval"]; ok { + queryOptions.MinInterval = &val + } + if val, ok := jsonData.QueryOptions["cacheTimeout"]; ok { + queryOptions.CacheTimeout = &val + } + meta.QueryOptions = queryOptions + } + + // Map Includes + if len(jsonData.Includes) > 0 { + meta.Includes = make([]pluginsv0alpha1.MetaInclude, 0, len(jsonData.Includes)) + for _, include := range jsonData.Includes { + v0Include := pluginsv0alpha1.MetaInclude{} + if include.UID != "" { + v0Include.Uid = &include.UID + } + if include.Type != "" { + var includeType pluginsv0alpha1.MetaIncludeType + switch include.Type { + case "dashboard": + includeType = pluginsv0alpha1.MetaIncludeTypeDashboard + case "page": + includeType = pluginsv0alpha1.MetaIncludeTypePage + case "panel": + includeType = pluginsv0alpha1.MetaIncludeTypePanel + case "datasource": + includeType = pluginsv0alpha1.MetaIncludeTypeDatasource + } + v0Include.Type = &includeType + } + if include.Name != "" { + v0Include.Name = &include.Name + } + if include.Component != "" { + v0Include.Component = &include.Component + } + if include.Role != "" { + var role pluginsv0alpha1.MetaIncludeRole + switch include.Role { + case identity.RoleAdmin: + role = pluginsv0alpha1.MetaIncludeRoleAdmin + case identity.RoleEditor: + role = pluginsv0alpha1.MetaIncludeRoleEditor + case identity.RoleViewer: + role = pluginsv0alpha1.MetaIncludeRoleViewer + case identity.RoleNone: + role = pluginsv0alpha1.MetaIncludeRoleNone + } + v0Include.Role = &role + } + if include.Action != "" { + v0Include.Action = &include.Action + } + if include.Path != "" { + v0Include.Path = &include.Path + } + if include.AddToNav { + v0Include.AddToNav = &include.AddToNav + } + if include.DefaultNav { + v0Include.DefaultNav = &include.DefaultNav + } + if include.Icon != "" { + v0Include.Icon = &include.Icon + } + meta.Includes = append(meta.Includes, v0Include) + } + } + + // Map Routes + if len(jsonData.Routes) > 0 { + meta.Routes = make([]pluginsv0alpha1.MetaRoute, 0, len(jsonData.Routes)) + for _, route := range jsonData.Routes { + v0Route := pluginsv0alpha1.MetaRoute{} + if route.Path != "" { + v0Route.Path = &route.Path + } + if route.Method != "" { + v0Route.Method = &route.Method + } + if route.URL != "" { + v0Route.Url = &route.URL + } + if route.ReqRole != "" { + reqRole := string(route.ReqRole) + v0Route.ReqRole = &reqRole + } + if route.ReqAction != "" { + v0Route.ReqAction = &route.ReqAction + } + if len(route.Headers) > 0 { + headers := make([]string, 0, len(route.Headers)) + for _, header := range route.Headers { + headers = append(headers, header.Name+": "+header.Content) + } + v0Route.Headers = headers + } + if len(route.URLParams) > 0 { + v0Route.UrlParams = make([]pluginsv0alpha1.MetaV0alpha1RouteUrlParams, 0, len(route.URLParams)) + for _, param := range route.URLParams { + v0Param := pluginsv0alpha1.MetaV0alpha1RouteUrlParams{} + if param.Name != "" { + v0Param.Name = ¶m.Name + } + if param.Content != "" { + v0Param.Content = ¶m.Content + } + v0Route.UrlParams = append(v0Route.UrlParams, v0Param) + } + } + if route.TokenAuth != nil { + v0Route.TokenAuth = &pluginsv0alpha1.MetaV0alpha1RouteTokenAuth{} + if route.TokenAuth.Url != "" { + v0Route.TokenAuth.Url = &route.TokenAuth.Url + } + if len(route.TokenAuth.Scopes) > 0 { + v0Route.TokenAuth.Scopes = route.TokenAuth.Scopes + } + if len(route.TokenAuth.Params) > 0 { + v0Route.TokenAuth.Params = make(map[string]interface{}) + for k, v := range route.TokenAuth.Params { + v0Route.TokenAuth.Params[k] = v + } + } + } + if route.JwtTokenAuth != nil { + v0Route.JwtTokenAuth = &pluginsv0alpha1.MetaV0alpha1RouteJwtTokenAuth{} + if route.JwtTokenAuth.Url != "" { + v0Route.JwtTokenAuth.Url = &route.JwtTokenAuth.Url + } + if len(route.JwtTokenAuth.Scopes) > 0 { + v0Route.JwtTokenAuth.Scopes = route.JwtTokenAuth.Scopes + } + if len(route.JwtTokenAuth.Params) > 0 { + v0Route.JwtTokenAuth.Params = make(map[string]interface{}) + for k, v := range route.JwtTokenAuth.Params { + v0Route.JwtTokenAuth.Params[k] = v + } + } + } + if len(route.Body) > 0 { + var bodyMap map[string]interface{} + if err := json.Unmarshal(route.Body, &bodyMap); err == nil { + v0Route.Body = bodyMap + } + } + meta.Routes = append(meta.Routes, v0Route) + } + } + + // Map Extensions + if len(jsonData.Extensions.AddedLinks) > 0 || len(jsonData.Extensions.AddedComponents) > 0 || + len(jsonData.Extensions.ExposedComponents) > 0 || len(jsonData.Extensions.ExtensionPoints) > 0 || + len(jsonData.Extensions.AddedFunctions) > 0 { + extensions := &pluginsv0alpha1.MetaExtensions{} + + if len(jsonData.Extensions.AddedLinks) > 0 { + extensions.AddedLinks = make([]pluginsv0alpha1.MetaV0alpha1ExtensionsAddedLinks, 0, len(jsonData.Extensions.AddedLinks)) + for _, link := range jsonData.Extensions.AddedLinks { + v0Link := pluginsv0alpha1.MetaV0alpha1ExtensionsAddedLinks{ + Targets: link.Targets, + Title: link.Title, + } + if link.Description != "" { + v0Link.Description = &link.Description + } + extensions.AddedLinks = append(extensions.AddedLinks, v0Link) + } + } + + if len(jsonData.Extensions.AddedComponents) > 0 { + extensions.AddedComponents = make([]pluginsv0alpha1.MetaV0alpha1ExtensionsAddedComponents, 0, len(jsonData.Extensions.AddedComponents)) + for _, comp := range jsonData.Extensions.AddedComponents { + v0Comp := pluginsv0alpha1.MetaV0alpha1ExtensionsAddedComponents{ + Targets: comp.Targets, + Title: comp.Title, + } + if comp.Description != "" { + v0Comp.Description = &comp.Description + } + extensions.AddedComponents = append(extensions.AddedComponents, v0Comp) + } + } + + if len(jsonData.Extensions.AddedFunctions) > 0 { + extensions.AddedFunctions = make([]pluginsv0alpha1.MetaV0alpha1ExtensionsAddedFunctions, 0, len(jsonData.Extensions.AddedFunctions)) + for _, comp := range jsonData.Extensions.AddedFunctions { + v0Comp := pluginsv0alpha1.MetaV0alpha1ExtensionsAddedFunctions{ + Targets: comp.Targets, + Title: comp.Title, + } + if comp.Description != "" { + v0Comp.Description = &comp.Description + } + extensions.AddedFunctions = append(extensions.AddedFunctions, v0Comp) + } + } + + if len(jsonData.Extensions.ExposedComponents) > 0 { + extensions.ExposedComponents = make([]pluginsv0alpha1.MetaV0alpha1ExtensionsExposedComponents, 0, len(jsonData.Extensions.ExposedComponents)) + for _, comp := range jsonData.Extensions.ExposedComponents { + v0Comp := pluginsv0alpha1.MetaV0alpha1ExtensionsExposedComponents{ + Id: comp.Id, + } + if comp.Title != "" { + v0Comp.Title = &comp.Title + } + if comp.Description != "" { + v0Comp.Description = &comp.Description + } + extensions.ExposedComponents = append(extensions.ExposedComponents, v0Comp) + } + } + + if len(jsonData.Extensions.ExtensionPoints) > 0 { + extensions.ExtensionPoints = make([]pluginsv0alpha1.MetaV0alpha1ExtensionsExtensionPoints, 0, len(jsonData.Extensions.ExtensionPoints)) + for _, point := range jsonData.Extensions.ExtensionPoints { + v0Point := pluginsv0alpha1.MetaV0alpha1ExtensionsExtensionPoints{ + Id: point.Id, + } + if point.Title != "" { + v0Point.Title = &point.Title + } + if point.Description != "" { + v0Point.Description = &point.Description + } + extensions.ExtensionPoints = append(extensions.ExtensionPoints, v0Point) + } + } + + meta.Extensions = extensions + } + + // Map Roles + if len(jsonData.Roles) > 0 { + meta.Roles = make([]pluginsv0alpha1.MetaRole, 0, len(jsonData.Roles)) + for _, role := range jsonData.Roles { + v0Role := pluginsv0alpha1.MetaRole{ + Grants: role.Grants, + } + if role.Role.Name != "" || role.Role.Description != "" || len(role.Role.Permissions) > 0 { + v0RoleRole := &pluginsv0alpha1.MetaV0alpha1RoleRole{} + if role.Role.Name != "" { + v0RoleRole.Name = &role.Role.Name + } + if role.Role.Description != "" { + v0RoleRole.Description = &role.Role.Description + } + if len(role.Role.Permissions) > 0 { + v0RoleRole.Permissions = make([]pluginsv0alpha1.MetaV0alpha1RoleRolePermissions, 0, len(role.Role.Permissions)) + for _, perm := range role.Role.Permissions { + v0Perm := pluginsv0alpha1.MetaV0alpha1RoleRolePermissions{} + if perm.Action != "" { + v0Perm.Action = &perm.Action + } + if perm.Scope != "" { + v0Perm.Scope = &perm.Scope + } + v0RoleRole.Permissions = append(v0RoleRole.Permissions, v0Perm) + } + } + v0Role.Role = v0RoleRole + } + meta.Roles = append(meta.Roles, v0Role) + } + } + + // Map IAM + if jsonData.IAM != nil && len(jsonData.IAM.Permissions) > 0 { + iam := &pluginsv0alpha1.MetaIAM{ + Permissions: make([]pluginsv0alpha1.MetaV0alpha1IAMPermissions, 0, len(jsonData.IAM.Permissions)), + } + for _, perm := range jsonData.IAM.Permissions { + v0Perm := pluginsv0alpha1.MetaV0alpha1IAMPermissions{} + if perm.Action != "" { + v0Perm.Action = &perm.Action + } + if perm.Scope != "" { + v0Perm.Scope = &perm.Scope + } + iam.Permissions = append(iam.Permissions, v0Perm) + } + meta.Iam = iam + } + + return meta +} + +// pluginStorePluginToMeta converts a pluginstore.Plugin to a pluginsv0alpha1.MetaSpec. +// This is similar to pluginToPluginMetaSpec but works with the plugin store DTO. +// loadingStrategy and moduleHash are optional calculated values that can be provided. +func pluginStorePluginToMeta(plugin pluginstore.Plugin, loadingStrategy plugins.LoadingStrategy, moduleHash string) pluginsv0alpha1.MetaSpec { + metaSpec := pluginsv0alpha1.MetaSpec{ + PluginJson: jsonDataToMetaJSONData(plugin.JSONData), + } + + // Set Class - default to External if not specified + var c pluginsv0alpha1.MetaSpecClass + if plugin.Class == plugins.ClassCore { + c = pluginsv0alpha1.MetaSpecClassCore + } else { + c = pluginsv0alpha1.MetaSpecClassExternal + } + metaSpec.Class = c + + if plugin.Module != "" { + module := &pluginsv0alpha1.MetaV0alpha1SpecModule{ + Path: plugin.Module, + } + if moduleHash != "" { + module.Hash = &moduleHash + } + if loadingStrategy != "" { + var ls pluginsv0alpha1.MetaV0alpha1SpecModuleLoadingStrategy + switch loadingStrategy { + case plugins.LoadingStrategyFetch: + ls = pluginsv0alpha1.MetaV0alpha1SpecModuleLoadingStrategyFetch + case plugins.LoadingStrategyScript: + ls = pluginsv0alpha1.MetaV0alpha1SpecModuleLoadingStrategyScript + } + module.LoadingStrategy = &ls + } + metaSpec.Module = module + } + + if plugin.BaseURL != "" { + metaSpec.BaseURL = &plugin.BaseURL + } + + if plugin.Signature != "" { + signature := &pluginsv0alpha1.MetaV0alpha1SpecSignature{ + Status: convertSignatureStatus(plugin.Signature), + } + + if plugin.SignatureType != "" { + sigType := convertSignatureType(plugin.SignatureType) + signature.Type = &sigType + } + + if plugin.SignatureOrg != "" { + signature.Org = &plugin.SignatureOrg + } + + metaSpec.Signature = signature + } + + if len(plugin.Children) > 0 { + metaSpec.Children = plugin.Children + } + + metaSpec.Angular = &pluginsv0alpha1.MetaV0alpha1SpecAngular{ + Detected: plugin.Angular.Detected, + } + + if len(plugin.Translations) > 0 { + metaSpec.Translations = plugin.Translations + } + + return metaSpec +} + +// convertSignatureStatus converts plugins.SignatureStatus to pluginsv0alpha1.MetaV0alpha1SpecSignatureStatus. +func convertSignatureStatus(status plugins.SignatureStatus) pluginsv0alpha1.MetaV0alpha1SpecSignatureStatus { + switch status { + case plugins.SignatureStatusInternal: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureStatusInternal + case plugins.SignatureStatusValid: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureStatusValid + case plugins.SignatureStatusInvalid: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureStatusInvalid + case plugins.SignatureStatusModified: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureStatusModified + case plugins.SignatureStatusUnsigned: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureStatusUnsigned + default: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureStatusUnsigned + } +} + +// convertSignatureType converts plugins.SignatureType to pluginsv0alpha1.MetaV0alpha1SpecSignatureType. +func convertSignatureType(sigType plugins.SignatureType) pluginsv0alpha1.MetaV0alpha1SpecSignatureType { + switch sigType { + case plugins.SignatureTypeGrafana: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureTypeGrafana + case plugins.SignatureTypeCommercial: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureTypeCommercial + case plugins.SignatureTypeCommunity: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureTypeCommunity + case plugins.SignatureTypePrivate: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureTypePrivate + case plugins.SignatureTypePrivateGlob: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureTypePrivateGlob + default: + return pluginsv0alpha1.MetaV0alpha1SpecSignatureTypeGrafana + } +} + +// pluginToMetaSpec converts a fully loaded *plugins.Plugin to a pluginsv0alpha1.MetaSpec. +func pluginToMetaSpec(plugin *plugins.Plugin) pluginsv0alpha1.MetaSpec { + metaSpec := pluginsv0alpha1.MetaSpec{ + PluginJson: jsonDataToMetaJSONData(plugin.JSONData), + } + + // Set Class - default to External if not specified + var c pluginsv0alpha1.MetaSpecClass + if plugin.Class == plugins.ClassCore { + c = pluginsv0alpha1.MetaSpecClassCore + } else { + c = pluginsv0alpha1.MetaSpecClassExternal + } + metaSpec.Class = c + + // Set module information + if plugin.Module != "" { + module := &pluginsv0alpha1.MetaV0alpha1SpecModule{ + Path: plugin.Module, + } + + loadingStrategy := pluginsv0alpha1.MetaV0alpha1SpecModuleLoadingStrategyScript + module.LoadingStrategy = &loadingStrategy + + metaSpec.Module = module + } + + // Set BaseURL + if plugin.BaseURL != "" { + metaSpec.BaseURL = &plugin.BaseURL + } + + // Set signature information + signature := &pluginsv0alpha1.MetaV0alpha1SpecSignature{ + Status: convertSignatureStatus(plugin.Signature), + } + + if plugin.SignatureType != "" { + sigType := convertSignatureType(plugin.SignatureType) + signature.Type = &sigType + } + + if plugin.SignatureOrg != "" { + signature.Org = &plugin.SignatureOrg + } + + metaSpec.Signature = signature + + if len(plugin.Children) > 0 { + children := make([]string, 0, len(plugin.Children)) + for _, child := range plugin.Children { + children = append(children, child.ID) + } + metaSpec.Children = children + } + + metaSpec.Angular = &pluginsv0alpha1.MetaV0alpha1SpecAngular{ + Detected: plugin.Angular.Detected, + } + + if len(plugin.Translations) > 0 { + metaSpec.Translations = plugin.Translations + } + + return metaSpec +} + +// grafanaComPluginVersionMeta represents the response from grafana.com API +// GET /api/plugins/{pluginId}/versions/{version} +type grafanaComPluginVersionMeta struct { + PluginID string `json:"pluginSlug"` + Version string `json:"version"` + URL string `json:"url"` + Commit string `json:"commit"` + Description string `json:"description"` + Keywords []string `json:"keywords"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + JSON pluginsv0alpha1.MetaJSONData `json:"json"` + Readme string `json:"readme"` + Downloads int `json:"downloads"` + Verified bool `json:"verified"` + Status string `json:"status"` + StatusContext string `json:"statusContext"` + DownloadSlug string `json:"downloadSlug"` + SignatureType string `json:"signatureType"` + SignedByOrg string `json:"signedByOrg"` + SignedByOrgName string `json:"signedByOrgName"` + Packages struct { + Any struct { + Md5 string `json:"md5"` + Sha256 string `json:"sha256"` + PackageName string `json:"packageName"` + DownloadURL string `json:"downloadUrl"` + } `json:"any"` + } `json:"packages"` + Links []struct { + Rel string `json:"rel"` + Href string `json:"href"` + } `json:"links"` + AngularDetected bool `json:"angularDetected"` + Scopes []string `json:"scopes"` +} + +// grafanaComPluginVersionMetaToMetaSpec converts a grafanaComPluginVersionMeta to a pluginsv0alpha1.MetaSpec. +func grafanaComPluginVersionMetaToMetaSpec(gcomMeta grafanaComPluginVersionMeta) pluginsv0alpha1.MetaSpec { + metaSpec := pluginsv0alpha1.MetaSpec{ + PluginJson: gcomMeta.JSON, + Class: pluginsv0alpha1.MetaSpecClassExternal, + } + + if gcomMeta.SignatureType != "" { + signature := &pluginsv0alpha1.MetaV0alpha1SpecSignature{ + Status: pluginsv0alpha1.MetaV0alpha1SpecSignatureStatusValid, + } + + switch gcomMeta.SignatureType { + case "grafana": + sigType := pluginsv0alpha1.MetaV0alpha1SpecSignatureTypeGrafana + signature.Type = &sigType + case "commercial": + sigType := pluginsv0alpha1.MetaV0alpha1SpecSignatureTypeCommercial + signature.Type = &sigType + case "community": + sigType := pluginsv0alpha1.MetaV0alpha1SpecSignatureTypeCommunity + signature.Type = &sigType + case "private": + sigType := pluginsv0alpha1.MetaV0alpha1SpecSignatureTypePrivate + signature.Type = &sigType + case "private-glob": + sigType := pluginsv0alpha1.MetaV0alpha1SpecSignatureTypePrivateGlob + signature.Type = &sigType + } + + if gcomMeta.SignedByOrg != "" { + signature.Org = &gcomMeta.SignedByOrg + } + + metaSpec.Signature = signature + } + + // Set angular info + metaSpec.Angular = &pluginsv0alpha1.MetaV0alpha1SpecAngular{ + Detected: gcomMeta.AngularDetected, + } + + return metaSpec +} diff --git a/apps/plugins/pkg/app/meta/core.go b/apps/plugins/pkg/app/meta/core.go index 3452f95b24b..1837386f7a3 100644 --- a/apps/plugins/pkg/app/meta/core.go +++ b/apps/plugins/pkg/app/meta/core.go @@ -2,7 +2,6 @@ package meta import ( "context" - "encoding/json" "errors" "os" "path/filepath" @@ -13,7 +12,15 @@ import ( pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1" "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/plugins/config" + pluginsLoader "github.com/grafana/grafana/pkg/plugins/manager/loader" + "github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap" + "github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery" + "github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization" + "github.com/grafana/grafana/pkg/plugins/manager/pipeline/termination" + "github.com/grafana/grafana/pkg/plugins/manager/pipeline/validation" "github.com/grafana/grafana/pkg/plugins/manager/sources" + "github.com/grafana/grafana/pkg/plugins/pluginerrs" ) const ( @@ -23,9 +30,10 @@ const ( // CoreProvider retrieves plugin metadata for core plugins. type CoreProvider struct { mu sync.RWMutex - loadedPlugins map[string]pluginsv0alpha1.PluginMetaJSONData + loadedPlugins map[string]pluginsv0alpha1.MetaSpec initialized bool ttl time.Duration + loader pluginsLoader.Service } // NewCoreProvider creates a new CoreProvider for core plugins. @@ -35,9 +43,13 @@ func NewCoreProvider() *CoreProvider { // NewCoreProviderWithTTL creates a new CoreProvider with a custom TTL. func NewCoreProviderWithTTL(ttl time.Duration) *CoreProvider { + cfg := &config.PluginManagementCfg{ + Features: config.Features{}, + } return &CoreProvider{ - loadedPlugins: make(map[string]pluginsv0alpha1.PluginMetaJSONData), + loadedPlugins: make(map[string]pluginsv0alpha1.MetaSpec), ttl: ttl, + loader: createLoader(cfg), } } @@ -76,9 +88,9 @@ func (p *CoreProvider) GetMeta(ctx context.Context, pluginID, _ string) (*Result p.initialized = true } - if meta, found := p.loadedPlugins[pluginID]; found { + if spec, found := p.loadedPlugins[pluginID]; found { return &Result{ - Meta: meta, + Meta: spec, TTL: p.ttl, }, nil } @@ -86,8 +98,8 @@ func (p *CoreProvider) GetMeta(ctx context.Context, pluginID, _ string) (*Result return nil, ErrMetaNotFound } -// loadPlugins discovers and caches all core plugins. -// Returns an error if the static root path cannot be found or if plugin discovery fails. +// loadPlugins discovers and caches all core plugins by fully loading them. +// Returns an error if the static root path cannot be found or if plugin loading fails. // This error will be handled gracefully by GetMeta, which will return ErrMetaNotFound // to allow other providers to handle the request. func (p *CoreProvider) loadPlugins(ctx context.Context) error { @@ -108,496 +120,51 @@ func (p *CoreProvider) loadPlugins(ctx context.Context) error { panelPath := filepath.Join(staticRootPath, "app", "plugins", "panel") src := sources.NewLocalSource(plugins.ClassCore, []string{datasourcePath, panelPath}) - ps, err := src.Discover(ctx) + loadedPlugins, err := p.loader.Load(ctx, src) if err != nil { return err } - if len(ps) == 0 { - logging.DefaultLogger.Warn("CoreProvider: no core plugins found during discovery") + if len(loadedPlugins) == 0 { + logging.DefaultLogger.Warn("CoreProvider: no core plugins found during loading") return nil } - for _, bundle := range ps { - meta := jsonDataToPluginMetaJSONData(bundle.Primary.JSONData) - p.loadedPlugins[bundle.Primary.JSONData.ID] = meta + for _, plugin := range loadedPlugins { + metaSpec := pluginToMetaSpec(plugin) + p.loadedPlugins[plugin.ID] = metaSpec } return nil } -// jsonDataToPluginMetaJSONData converts a plugins.JSONData to a pluginsv0alpha1.PluginMetaJSONData. -// nolint:gocyclo -func jsonDataToPluginMetaJSONData(jsonData plugins.JSONData) pluginsv0alpha1.PluginMetaJSONData { - meta := pluginsv0alpha1.PluginMetaJSONData{ - Id: jsonData.ID, - Name: jsonData.Name, - } - - // Map plugin type - switch jsonData.Type { - case plugins.TypeApp: - meta.Type = pluginsv0alpha1.PluginMetaJSONDataTypeApp - case plugins.TypeDataSource: - meta.Type = pluginsv0alpha1.PluginMetaJSONDataTypeDatasource - case plugins.TypePanel: - meta.Type = pluginsv0alpha1.PluginMetaJSONDataTypePanel - case plugins.TypeRenderer: - meta.Type = pluginsv0alpha1.PluginMetaJSONDataTypeRenderer - } - - // Map Info - meta.Info = pluginsv0alpha1.PluginMetaInfo{ - Keywords: jsonData.Info.Keywords, - Logos: pluginsv0alpha1.PluginMetaV0alpha1InfoLogos{ - Small: jsonData.Info.Logos.Small, - Large: jsonData.Info.Logos.Large, +// createLoader creates a loader service configured for core plugins. +func createLoader(cfg *config.PluginManagementCfg) pluginsLoader.Service { + d := discovery.New(cfg, discovery.Opts{ + FilterFuncs: []discovery.FilterFunc{ + // Allow all plugin types for core plugins }, - Updated: jsonData.Info.Updated, - Version: jsonData.Info.Version, - } + }) + b := bootstrap.New(cfg, bootstrap.Opts{ + DecorateFuncs: []bootstrap.DecorateFunc{}, // no decoration required for metadata + }) + v := validation.New(cfg, validation.Opts{ + ValidateFuncs: []validation.ValidateFunc{ + // Skip validation for core plugins - they're trusted + }, + }) + i := initialization.New(cfg, initialization.Opts{ + InitializeFuncs: []initialization.InitializeFunc{ + // Skip initialization - we only need metadata, not running plugins + }, + }) + t, _ := termination.New(cfg, termination.Opts{ + TerminateFuncs: []termination.TerminateFunc{ + // No termination needed for metadata-only loading + }, + }) - if jsonData.Info.Description != "" { - meta.Info.Description = &jsonData.Info.Description - } + et := pluginerrs.ProvideErrorTracker() - if jsonData.Info.Author.Name != "" || jsonData.Info.Author.URL != "" { - author := &pluginsv0alpha1.PluginMetaV0alpha1InfoAuthor{} - if jsonData.Info.Author.Name != "" { - author.Name = &jsonData.Info.Author.Name - } - if jsonData.Info.Author.URL != "" { - author.Url = &jsonData.Info.Author.URL - } - meta.Info.Author = author - } - - if len(jsonData.Info.Links) > 0 { - meta.Info.Links = make([]pluginsv0alpha1.PluginMetaV0alpha1InfoLinks, 0, len(jsonData.Info.Links)) - for _, link := range jsonData.Info.Links { - v0Link := pluginsv0alpha1.PluginMetaV0alpha1InfoLinks{} - if link.Name != "" { - v0Link.Name = &link.Name - } - if link.URL != "" { - v0Link.Url = &link.URL - } - meta.Info.Links = append(meta.Info.Links, v0Link) - } - } - - if len(jsonData.Info.Screenshots) > 0 { - meta.Info.Screenshots = make([]pluginsv0alpha1.PluginMetaV0alpha1InfoScreenshots, 0, len(jsonData.Info.Screenshots)) - for _, screenshot := range jsonData.Info.Screenshots { - v0Screenshot := pluginsv0alpha1.PluginMetaV0alpha1InfoScreenshots{} - if screenshot.Name != "" { - v0Screenshot.Name = &screenshot.Name - } - if screenshot.Path != "" { - v0Screenshot.Path = &screenshot.Path - } - meta.Info.Screenshots = append(meta.Info.Screenshots, v0Screenshot) - } - } - - // Map Dependencies - meta.Dependencies = pluginsv0alpha1.PluginMetaDependencies{ - GrafanaDependency: jsonData.Dependencies.GrafanaDependency, - } - - if jsonData.Dependencies.GrafanaVersion != "" { - meta.Dependencies.GrafanaVersion = &jsonData.Dependencies.GrafanaVersion - } - - if len(jsonData.Dependencies.Plugins) > 0 { - meta.Dependencies.Plugins = make([]pluginsv0alpha1.PluginMetaV0alpha1DependenciesPlugins, 0, len(jsonData.Dependencies.Plugins)) - for _, dep := range jsonData.Dependencies.Plugins { - var depType pluginsv0alpha1.PluginMetaV0alpha1DependenciesPluginsType - switch dep.Type { - case "app": - depType = pluginsv0alpha1.PluginMetaV0alpha1DependenciesPluginsTypeApp - case "datasource": - depType = pluginsv0alpha1.PluginMetaV0alpha1DependenciesPluginsTypeDatasource - case "panel": - depType = pluginsv0alpha1.PluginMetaV0alpha1DependenciesPluginsTypePanel - } - meta.Dependencies.Plugins = append(meta.Dependencies.Plugins, pluginsv0alpha1.PluginMetaV0alpha1DependenciesPlugins{ - Id: dep.ID, - Type: depType, - Name: dep.Name, - }) - } - } - - if len(jsonData.Dependencies.Extensions.ExposedComponents) > 0 { - meta.Dependencies.Extensions = &pluginsv0alpha1.PluginMetaV0alpha1DependenciesExtensions{ - ExposedComponents: jsonData.Dependencies.Extensions.ExposedComponents, - } - } - - // Map optional boolean fields - if jsonData.Alerting { - meta.Alerting = &jsonData.Alerting - } - if jsonData.Annotations { - meta.Annotations = &jsonData.Annotations - } - if jsonData.AutoEnabled { - meta.AutoEnabled = &jsonData.AutoEnabled - } - if jsonData.Backend { - meta.Backend = &jsonData.Backend - } - if jsonData.BuiltIn { - meta.BuiltIn = &jsonData.BuiltIn - } - if jsonData.HideFromList { - meta.HideFromList = &jsonData.HideFromList - } - if jsonData.Logs { - meta.Logs = &jsonData.Logs - } - if jsonData.Metrics { - meta.Metrics = &jsonData.Metrics - } - if jsonData.MultiValueFilterOperators { - meta.MultiValueFilterOperators = &jsonData.MultiValueFilterOperators - } - if jsonData.Preload { - meta.Preload = &jsonData.Preload - } - if jsonData.SkipDataQuery { - meta.SkipDataQuery = &jsonData.SkipDataQuery - } - if jsonData.Streaming { - meta.Streaming = &jsonData.Streaming - } - if jsonData.Tracing { - meta.Tracing = &jsonData.Tracing - } - - // Map category - if jsonData.Category != "" { - var category pluginsv0alpha1.PluginMetaJSONDataCategory - switch jsonData.Category { - case "tsdb": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryTsdb - case "logging": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryLogging - case "cloud": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryCloud - case "tracing": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryTracing - case "profiling": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryProfiling - case "sql": - category = pluginsv0alpha1.PluginMetaJSONDataCategorySql - case "enterprise": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryEnterprise - case "iot": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryIot - case "other": - category = pluginsv0alpha1.PluginMetaJSONDataCategoryOther - default: - category = pluginsv0alpha1.PluginMetaJSONDataCategoryOther - } - meta.Category = &category - } - - // Map state - if jsonData.State != "" { - var state pluginsv0alpha1.PluginMetaJSONDataState - switch jsonData.State { - case plugins.ReleaseStateAlpha: - state = pluginsv0alpha1.PluginMetaJSONDataStateAlpha - case plugins.ReleaseStateBeta: - state = pluginsv0alpha1.PluginMetaJSONDataStateBeta - default: - } - if state != "" { - meta.State = &state - } - } - - // Map executable - if jsonData.Executable != "" { - meta.Executable = &jsonData.Executable - } - - // Map QueryOptions - if len(jsonData.QueryOptions) > 0 { - queryOptions := &pluginsv0alpha1.PluginMetaQueryOptions{} - if val, ok := jsonData.QueryOptions["maxDataPoints"]; ok { - queryOptions.MaxDataPoints = &val - } - if val, ok := jsonData.QueryOptions["minInterval"]; ok { - queryOptions.MinInterval = &val - } - if val, ok := jsonData.QueryOptions["cacheTimeout"]; ok { - queryOptions.CacheTimeout = &val - } - meta.QueryOptions = queryOptions - } - - // Map Includes - if len(jsonData.Includes) > 0 { - meta.Includes = make([]pluginsv0alpha1.PluginMetaInclude, 0, len(jsonData.Includes)) - for _, include := range jsonData.Includes { - v0Include := pluginsv0alpha1.PluginMetaInclude{} - if include.UID != "" { - v0Include.Uid = &include.UID - } - if include.Type != "" { - var includeType pluginsv0alpha1.PluginMetaIncludeType - switch include.Type { - case "dashboard": - includeType = pluginsv0alpha1.PluginMetaIncludeTypeDashboard - case "page": - includeType = pluginsv0alpha1.PluginMetaIncludeTypePage - case "panel": - includeType = pluginsv0alpha1.PluginMetaIncludeTypePanel - case "datasource": - includeType = pluginsv0alpha1.PluginMetaIncludeTypeDatasource - } - v0Include.Type = &includeType - } - if include.Name != "" { - v0Include.Name = &include.Name - } - if include.Component != "" { - v0Include.Component = &include.Component - } - if include.Role != "" { - var role pluginsv0alpha1.PluginMetaIncludeRole - switch include.Role { - case "Admin": - role = pluginsv0alpha1.PluginMetaIncludeRoleAdmin - case "Editor": - role = pluginsv0alpha1.PluginMetaIncludeRoleEditor - case "Viewer": - role = pluginsv0alpha1.PluginMetaIncludeRoleViewer - } - v0Include.Role = &role - } - if include.Action != "" { - v0Include.Action = &include.Action - } - if include.Path != "" { - v0Include.Path = &include.Path - } - if include.AddToNav { - v0Include.AddToNav = &include.AddToNav - } - if include.DefaultNav { - v0Include.DefaultNav = &include.DefaultNav - } - if include.Icon != "" { - v0Include.Icon = &include.Icon - } - meta.Includes = append(meta.Includes, v0Include) - } - } - - // Map Routes - if len(jsonData.Routes) > 0 { - meta.Routes = make([]pluginsv0alpha1.PluginMetaRoute, 0, len(jsonData.Routes)) - for _, route := range jsonData.Routes { - v0Route := pluginsv0alpha1.PluginMetaRoute{} - if route.Path != "" { - v0Route.Path = &route.Path - } - if route.Method != "" { - v0Route.Method = &route.Method - } - if route.URL != "" { - v0Route.Url = &route.URL - } - if route.ReqRole != "" { - reqRole := string(route.ReqRole) - v0Route.ReqRole = &reqRole - } - if route.ReqAction != "" { - v0Route.ReqAction = &route.ReqAction - } - if len(route.Headers) > 0 { - headers := make([]string, 0, len(route.Headers)) - for _, header := range route.Headers { - headers = append(headers, header.Name+": "+header.Content) - } - v0Route.Headers = headers - } - if len(route.URLParams) > 0 { - v0Route.UrlParams = make([]pluginsv0alpha1.PluginMetaV0alpha1RouteUrlParams, 0, len(route.URLParams)) - for _, param := range route.URLParams { - v0Param := pluginsv0alpha1.PluginMetaV0alpha1RouteUrlParams{} - if param.Name != "" { - v0Param.Name = ¶m.Name - } - if param.Content != "" { - v0Param.Content = ¶m.Content - } - v0Route.UrlParams = append(v0Route.UrlParams, v0Param) - } - } - if route.TokenAuth != nil { - v0Route.TokenAuth = &pluginsv0alpha1.PluginMetaV0alpha1RouteTokenAuth{} - if route.TokenAuth.Url != "" { - v0Route.TokenAuth.Url = &route.TokenAuth.Url - } - if len(route.TokenAuth.Scopes) > 0 { - v0Route.TokenAuth.Scopes = route.TokenAuth.Scopes - } - if len(route.TokenAuth.Params) > 0 { - v0Route.TokenAuth.Params = make(map[string]interface{}) - for k, v := range route.TokenAuth.Params { - v0Route.TokenAuth.Params[k] = v - } - } - } - if route.JwtTokenAuth != nil { - v0Route.JwtTokenAuth = &pluginsv0alpha1.PluginMetaV0alpha1RouteJwtTokenAuth{} - if route.JwtTokenAuth.Url != "" { - v0Route.JwtTokenAuth.Url = &route.JwtTokenAuth.Url - } - if len(route.JwtTokenAuth.Scopes) > 0 { - v0Route.JwtTokenAuth.Scopes = route.JwtTokenAuth.Scopes - } - if len(route.JwtTokenAuth.Params) > 0 { - v0Route.JwtTokenAuth.Params = make(map[string]interface{}) - for k, v := range route.JwtTokenAuth.Params { - v0Route.JwtTokenAuth.Params[k] = v - } - } - } - if len(route.Body) > 0 { - var bodyMap map[string]interface{} - if err := json.Unmarshal(route.Body, &bodyMap); err == nil { - v0Route.Body = bodyMap - } - } - meta.Routes = append(meta.Routes, v0Route) - } - } - - // Map Extensions - if len(jsonData.Extensions.AddedLinks) > 0 || len(jsonData.Extensions.AddedComponents) > 0 || - len(jsonData.Extensions.ExposedComponents) > 0 || len(jsonData.Extensions.ExtensionPoints) > 0 { - extensions := &pluginsv0alpha1.PluginMetaExtensions{} - - if len(jsonData.Extensions.AddedLinks) > 0 { - extensions.AddedLinks = make([]pluginsv0alpha1.PluginMetaV0alpha1ExtensionsAddedLinks, 0, len(jsonData.Extensions.AddedLinks)) - for _, link := range jsonData.Extensions.AddedLinks { - v0Link := pluginsv0alpha1.PluginMetaV0alpha1ExtensionsAddedLinks{ - Targets: link.Targets, - Title: link.Title, - } - if link.Description != "" { - v0Link.Description = &link.Description - } - extensions.AddedLinks = append(extensions.AddedLinks, v0Link) - } - } - - if len(jsonData.Extensions.AddedComponents) > 0 { - extensions.AddedComponents = make([]pluginsv0alpha1.PluginMetaV0alpha1ExtensionsAddedComponents, 0, len(jsonData.Extensions.AddedComponents)) - for _, comp := range jsonData.Extensions.AddedComponents { - v0Comp := pluginsv0alpha1.PluginMetaV0alpha1ExtensionsAddedComponents{ - Targets: comp.Targets, - Title: comp.Title, - } - if comp.Description != "" { - v0Comp.Description = &comp.Description - } - extensions.AddedComponents = append(extensions.AddedComponents, v0Comp) - } - } - - if len(jsonData.Extensions.ExposedComponents) > 0 { - extensions.ExposedComponents = make([]pluginsv0alpha1.PluginMetaV0alpha1ExtensionsExposedComponents, 0, len(jsonData.Extensions.ExposedComponents)) - for _, comp := range jsonData.Extensions.ExposedComponents { - v0Comp := pluginsv0alpha1.PluginMetaV0alpha1ExtensionsExposedComponents{ - Id: comp.Id, - } - if comp.Title != "" { - v0Comp.Title = &comp.Title - } - if comp.Description != "" { - v0Comp.Description = &comp.Description - } - extensions.ExposedComponents = append(extensions.ExposedComponents, v0Comp) - } - } - - if len(jsonData.Extensions.ExtensionPoints) > 0 { - extensions.ExtensionPoints = make([]pluginsv0alpha1.PluginMetaV0alpha1ExtensionsExtensionPoints, 0, len(jsonData.Extensions.ExtensionPoints)) - for _, point := range jsonData.Extensions.ExtensionPoints { - v0Point := pluginsv0alpha1.PluginMetaV0alpha1ExtensionsExtensionPoints{ - Id: point.Id, - } - if point.Title != "" { - v0Point.Title = &point.Title - } - if point.Description != "" { - v0Point.Description = &point.Description - } - extensions.ExtensionPoints = append(extensions.ExtensionPoints, v0Point) - } - } - - meta.Extensions = extensions - } - - // Map Roles - if len(jsonData.Roles) > 0 { - meta.Roles = make([]pluginsv0alpha1.PluginMetaRole, 0, len(jsonData.Roles)) - for _, role := range jsonData.Roles { - v0Role := pluginsv0alpha1.PluginMetaRole{ - Grants: role.Grants, - } - if role.Role.Name != "" || role.Role.Description != "" || len(role.Role.Permissions) > 0 { - v0RoleRole := &pluginsv0alpha1.PluginMetaV0alpha1RoleRole{} - if role.Role.Name != "" { - v0RoleRole.Name = &role.Role.Name - } - if role.Role.Description != "" { - v0RoleRole.Description = &role.Role.Description - } - if len(role.Role.Permissions) > 0 { - v0RoleRole.Permissions = make([]pluginsv0alpha1.PluginMetaV0alpha1RoleRolePermissions, 0, len(role.Role.Permissions)) - for _, perm := range role.Role.Permissions { - v0Perm := pluginsv0alpha1.PluginMetaV0alpha1RoleRolePermissions{} - if perm.Action != "" { - v0Perm.Action = &perm.Action - } - if perm.Scope != "" { - v0Perm.Scope = &perm.Scope - } - v0RoleRole.Permissions = append(v0RoleRole.Permissions, v0Perm) - } - } - v0Role.Role = v0RoleRole - } - meta.Roles = append(meta.Roles, v0Role) - } - } - - // Map IAM - if jsonData.IAM != nil && len(jsonData.IAM.Permissions) > 0 { - iam := &pluginsv0alpha1.PluginMetaIAM{ - Permissions: make([]pluginsv0alpha1.PluginMetaV0alpha1IAMPermissions, 0, len(jsonData.IAM.Permissions)), - } - for _, perm := range jsonData.IAM.Permissions { - v0Perm := pluginsv0alpha1.PluginMetaV0alpha1IAMPermissions{} - if perm.Action != "" { - v0Perm.Action = &perm.Action - } - if perm.Scope != "" { - v0Perm.Scope = &perm.Scope - } - iam.Permissions = append(iam.Permissions, v0Perm) - } - meta.Iam = iam - } - - return meta + return pluginsLoader.New(cfg, d, b, v, i, t, et) } diff --git a/apps/plugins/pkg/app/meta/core_test.go b/apps/plugins/pkg/app/meta/core_test.go index a9d7103e4a2..d6f51057fab 100644 --- a/apps/plugins/pkg/app/meta/core_test.go +++ b/apps/plugins/pkg/app/meta/core_test.go @@ -22,10 +22,12 @@ func TestCoreProvider_GetMeta(t *testing.T) { t.Run("returns cached plugin when available", func(t *testing.T) { provider := NewCoreProvider() - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Test Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } provider.mu.Lock() @@ -58,10 +60,12 @@ func TestCoreProvider_GetMeta(t *testing.T) { t.Run("ignores version parameter", func(t *testing.T) { provider := NewCoreProvider() - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Test Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } provider.mu.Lock() @@ -81,10 +85,12 @@ func TestCoreProvider_GetMeta(t *testing.T) { customTTL := 2 * time.Hour provider := NewCoreProviderWithTTL(customTTL) - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Test Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } provider.mu.Lock() @@ -226,8 +232,8 @@ func TestCoreProvider_loadPlugins(t *testing.T) { if loaded { result, err := provider.GetMeta(ctx, "test-datasource", "1.0.0") require.NoError(t, err) - assert.Equal(t, "test-datasource", result.Meta.Id) - assert.Equal(t, "Test Datasource", result.Meta.Name) + assert.Equal(t, "test-datasource", result.Meta.PluginJson.Id) + assert.Equal(t, "Test Datasource", result.Meta.PluginJson.Name) } }) } @@ -271,11 +277,11 @@ func TestJsonDataToMeta(t *testing.T) { }, } - meta := jsonDataToPluginMetaJSONData(jsonData) + meta := jsonDataToMetaJSONData(jsonData) assert.Equal(t, "test-plugin", meta.Id) assert.Equal(t, "Test Plugin", meta.Name) - assert.Equal(t, pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, meta.Type) + assert.Equal(t, pluginsv0alpha1.MetaJSONDataTypeDatasource, meta.Type) assert.Equal(t, "1.0.0", meta.Info.Version) assert.Equal(t, "Test description", *meta.Info.Description) assert.Equal(t, []string{"test", "plugin"}, meta.Info.Keywords) @@ -293,7 +299,7 @@ func TestJsonDataToMeta(t *testing.T) { }, } - meta := jsonDataToPluginMetaJSONData(jsonData) + meta := jsonDataToMetaJSONData(jsonData) assert.Nil(t, meta.Info.Description) assert.Nil(t, meta.Info.Author) diff --git a/apps/plugins/pkg/app/meta/local.go b/apps/plugins/pkg/app/meta/local.go new file mode 100644 index 00000000000..2c699520cfc --- /dev/null +++ b/apps/plugins/pkg/app/meta/local.go @@ -0,0 +1,53 @@ +package meta + +import ( + "context" + "time" + + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" +) + +const ( + defaultLocalTTL = 1 * time.Hour +) + +// PluginAssetsCalculator is an interface for calculating plugin asset information. +// LocalProvider requires this to calculate loading strategy and module hash. +type PluginAssetsCalculator interface { + LoadingStrategy(ctx context.Context, p pluginstore.Plugin) plugins.LoadingStrategy + ModuleHash(ctx context.Context, p pluginstore.Plugin) string +} + +// LocalProvider retrieves plugin metadata for locally installed plugins. +// It uses the plugin store to access plugins that have already been loaded. +type LocalProvider struct { + store pluginstore.Store + pluginAssets PluginAssetsCalculator +} + +// NewLocalProvider creates a new LocalProvider for locally installed plugins. +// pluginAssets is required for calculating loading strategy and module hash. +func NewLocalProvider(pluginStore pluginstore.Store, pluginAssets PluginAssetsCalculator) *LocalProvider { + return &LocalProvider{ + store: pluginStore, + pluginAssets: pluginAssets, + } +} + +// GetMeta retrieves plugin metadata for locally installed plugins. +func (p *LocalProvider) GetMeta(ctx context.Context, pluginID, version string) (*Result, error) { + plugin, exists := p.store.Plugin(ctx, pluginID) + if !exists { + return nil, ErrMetaNotFound + } + + loadingStrategy := p.pluginAssets.LoadingStrategy(ctx, plugin) + moduleHash := p.pluginAssets.ModuleHash(ctx, plugin) + + spec := pluginStorePluginToMeta(plugin, loadingStrategy, moduleHash) + return &Result{ + Meta: spec, + TTL: defaultLocalTTL, + }, nil +} diff --git a/apps/plugins/pkg/app/meta/manager.go b/apps/plugins/pkg/app/meta/manager.go index e694e88bba7..d8cd1f554c2 100644 --- a/apps/plugins/pkg/app/meta/manager.go +++ b/apps/plugins/pkg/app/meta/manager.go @@ -16,7 +16,7 @@ const ( // cachedMeta represents a cached metadata entry with expiration time type cachedMeta struct { - meta pluginsv0alpha1.PluginMetaJSONData + meta pluginsv0alpha1.MetaSpec ttl time.Duration expiresAt time.Time } @@ -84,7 +84,7 @@ func (pm *ProviderManager) GetMeta(ctx context.Context, pluginID, version string if err == nil { // Don't cache results with a zero TTL if result.TTL == 0 { - continue + return result, nil } pm.cacheMu.Lock() diff --git a/apps/plugins/pkg/app/meta/manager_test.go b/apps/plugins/pkg/app/meta/manager_test.go index 3d3fe3c936c..c9a8a9f3a5f 100644 --- a/apps/plugins/pkg/app/meta/manager_test.go +++ b/apps/plugins/pkg/app/meta/manager_test.go @@ -35,10 +35,12 @@ func TestProviderManager_GetMeta(t *testing.T) { ctx := context.Background() t.Run("returns cached result when available and not expired", func(t *testing.T) { - cachedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + cachedMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Test Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } provider := &mockProvider{ @@ -60,8 +62,10 @@ func TestProviderManager_GetMeta(t *testing.T) { provider.getMetaFunc = func(ctx context.Context, pluginID, version string) (*Result, error) { return &Result{ - Meta: pluginsv0alpha1.PluginMetaJSONData{Id: "different"}, - TTL: time.Hour, + Meta: pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{Id: "different"}, + }, + TTL: time.Hour, }, nil } @@ -73,10 +77,12 @@ func TestProviderManager_GetMeta(t *testing.T) { }) t.Run("fetches from provider when not cached", func(t *testing.T) { - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Test Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } expectedTTL := 2 * time.Hour @@ -107,19 +113,16 @@ func TestProviderManager_GetMeta(t *testing.T) { assert.Equal(t, expectedTTL, cached.ttl) }) - t.Run("does not cache result with zero TTL and tries next provider", func(t *testing.T) { - zeroTTLMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Zero TTL Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, - } - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + t.Run("does not cache result with zero TTL", func(t *testing.T) { + zeroTTLMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Zero TTL Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } - provider1 := &mockProvider{ + provider := &mockProvider{ getMetaFunc: func(ctx context.Context, pluginID, version string) (*Result, error) { return &Result{ Meta: zeroTTLMeta, @@ -127,37 +130,30 @@ func TestProviderManager_GetMeta(t *testing.T) { }, nil }, } - provider2 := &mockProvider{ - getMetaFunc: func(ctx context.Context, pluginID, version string) (*Result, error) { - return &Result{ - Meta: expectedMeta, - TTL: time.Hour, - }, nil - }, - } - pm := NewProviderManager(provider1, provider2) + pm := NewProviderManager(provider) result, err := pm.GetMeta(ctx, "test-plugin", "1.0.0") require.NoError(t, err) require.NotNil(t, result) - assert.Equal(t, expectedMeta, result.Meta) + assert.Equal(t, zeroTTLMeta, result.Meta) + assert.Equal(t, time.Duration(0), result.TTL) pm.cacheMu.RLock() - cached, exists := pm.cache["test-plugin:1.0.0"] + _, exists := pm.cache["test-plugin:1.0.0"] pm.cacheMu.RUnlock() - assert.True(t, exists) - assert.Equal(t, expectedMeta, cached.meta) - assert.Equal(t, time.Hour, cached.ttl) + assert.False(t, exists, "zero TTL results should not be cached") }) t.Run("tries next provider when first returns ErrMetaNotFound", func(t *testing.T) { - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Test Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } provider1 := &mockProvider{ @@ -229,15 +225,19 @@ func TestProviderManager_GetMeta(t *testing.T) { }) t.Run("skips expired cache entries", func(t *testing.T) { - expiredMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Expired Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expiredMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Expired Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } - expectedMeta := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Test Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Test Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } callCount := 0 @@ -272,15 +272,19 @@ func TestProviderManager_GetMeta(t *testing.T) { }) t.Run("uses first successful provider", func(t *testing.T) { - expectedMeta1 := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Provider 1 Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta1 := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Provider 1 Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } - expectedMeta2 := pluginsv0alpha1.PluginMetaJSONData{ - Id: "test-plugin", - Name: "Provider 2 Plugin", - Type: pluginsv0alpha1.PluginMetaJSONDataTypeDatasource, + expectedMeta2 := pluginsv0alpha1.MetaSpec{ + PluginJson: pluginsv0alpha1.MetaJSONData{ + Id: "test-plugin", + Name: "Provider 2 Plugin", + Type: pluginsv0alpha1.MetaJSONDataTypeDatasource, + }, } provider1 := &mockProvider{ @@ -331,9 +335,9 @@ func TestProviderManager_Run(t *testing.T) { func TestProviderManager_cleanupExpired(t *testing.T) { t.Run("removes expired entries", func(t *testing.T) { - validMeta := pluginsv0alpha1.PluginMetaJSONData{Id: "valid"} - expiredMeta1 := pluginsv0alpha1.PluginMetaJSONData{Id: "expired1"} - expiredMeta2 := pluginsv0alpha1.PluginMetaJSONData{Id: "expired2"} + validMeta := pluginsv0alpha1.MetaSpec{PluginJson: pluginsv0alpha1.MetaJSONData{Id: "valid"}} + expiredMeta1 := pluginsv0alpha1.MetaSpec{PluginJson: pluginsv0alpha1.MetaJSONData{Id: "expired1"}} + expiredMeta2 := pluginsv0alpha1.MetaSpec{PluginJson: pluginsv0alpha1.MetaJSONData{Id: "expired2"}} provider := &mockProvider{ getMetaFunc: func(ctx context.Context, pluginID, version string) (*Result, error) { diff --git a/apps/plugins/pkg/app/meta/provider.go b/apps/plugins/pkg/app/meta/provider.go index 8b5d8b0fcbd..3c01361d656 100644 --- a/apps/plugins/pkg/app/meta/provider.go +++ b/apps/plugins/pkg/app/meta/provider.go @@ -14,14 +14,14 @@ var ( // Result contains plugin metadata along with its recommended TTL. type Result struct { - Meta pluginsv0alpha1.PluginMetaJSONData + Meta pluginsv0alpha1.MetaSpec TTL time.Duration } // Provider is used for retrieving plugin metadata. type Provider interface { // GetMeta retrieves plugin metadata for the given plugin ID and version. - // Returns the Result containing the PluginMetaJSONData and its recommended TTL. + // Returns the Result containing the MetaJSONData and its recommended TTL. // If the plugin is not found, returns ErrMetaNotFound. GetMeta(ctx context.Context, pluginID, version string) (*Result, error) } diff --git a/apps/plugins/pkg/app/storage.go b/apps/plugins/pkg/app/storage.go index 575b1ca21c8..01e62b9c4ec 100644 --- a/apps/plugins/pkg/app/storage.go +++ b/apps/plugins/pkg/app/storage.go @@ -22,15 +22,15 @@ import ( ) var ( - _ rest.Scoper = (*PluginMetaStorage)(nil) - _ rest.SingularNameProvider = (*PluginMetaStorage)(nil) - _ rest.Getter = (*PluginMetaStorage)(nil) - _ rest.Lister = (*PluginMetaStorage)(nil) - _ rest.Storage = (*PluginMetaStorage)(nil) - _ rest.TableConvertor = (*PluginMetaStorage)(nil) + _ rest.Scoper = (*MetaStorage)(nil) + _ rest.SingularNameProvider = (*MetaStorage)(nil) + _ rest.Getter = (*MetaStorage)(nil) + _ rest.Lister = (*MetaStorage)(nil) + _ rest.Storage = (*MetaStorage)(nil) + _ rest.TableConvertor = (*MetaStorage)(nil) ) -type PluginMetaStorage struct { +type MetaStorage struct { metaManager *meta.ProviderManager client *pluginsv0alpha1.PluginClient clientFactory func(context.Context) (*pluginsv0alpha1.PluginClient, error) @@ -41,16 +41,16 @@ type PluginMetaStorage struct { tableConverter rest.TableConvertor } -func NewPluginMetaStorage( +func NewMetaStorage( metaManager *meta.ProviderManager, clientFactory func(context.Context) (*pluginsv0alpha1.PluginClient, error), -) *PluginMetaStorage { +) *MetaStorage { gr := schema.GroupResource{ Group: pluginsv0alpha1.APIGroup, - Resource: strings.ToLower(pluginsv0alpha1.PluginMetaKind().Plural()), + Resource: strings.ToLower(pluginsv0alpha1.MetaKind().Plural()), } - return &PluginMetaStorage{ + return &MetaStorage{ metaManager: metaManager, clientFactory: clientFactory, gr: gr, @@ -58,7 +58,7 @@ func NewPluginMetaStorage( } } -func (s *PluginMetaStorage) getClient(ctx context.Context) (*pluginsv0alpha1.PluginClient, error) { +func (s *MetaStorage) getClient(ctx context.Context) (*pluginsv0alpha1.PluginClient, error) { s.clientOnce.Do(func() { client, err := s.clientFactory(ctx) if err != nil { @@ -72,29 +72,29 @@ func (s *PluginMetaStorage) getClient(ctx context.Context) (*pluginsv0alpha1.Plu return s.client, s.clientErr } -func (s *PluginMetaStorage) New() runtime.Object { - return pluginsv0alpha1.PluginMetaKind().ZeroValue() +func (s *MetaStorage) New() runtime.Object { + return pluginsv0alpha1.MetaKind().ZeroValue() } -func (s *PluginMetaStorage) Destroy() {} +func (s *MetaStorage) Destroy() {} -func (s *PluginMetaStorage) NamespaceScoped() bool { +func (s *MetaStorage) NamespaceScoped() bool { return true } -func (s *PluginMetaStorage) GetSingularName() string { - return strings.ToLower(pluginsv0alpha1.PluginMetaKind().Kind()) +func (s *MetaStorage) GetSingularName() string { + return strings.ToLower(pluginsv0alpha1.MetaKind().Kind()) } -func (s *PluginMetaStorage) NewList() runtime.Object { - return pluginsv0alpha1.PluginMetaKind().ZeroListValue() +func (s *MetaStorage) NewList() runtime.Object { + return pluginsv0alpha1.MetaKind().ZeroListValue() } -func (s *PluginMetaStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) { +func (s *MetaStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) { return s.tableConverter.ConvertToTable(ctx, object, tableOptions) } -func (s *PluginMetaStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) { +func (s *MetaStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) { ns, err := request.NamespaceInfoFrom(ctx, true) if err != nil { return nil, err @@ -111,8 +111,8 @@ func (s *PluginMetaStorage) List(ctx context.Context, options *internalversion.L return nil, apierrors.NewInternalError(fmt.Errorf("failed to list plugins: %w", err)) } - // Convert each Plugin to PluginMeta - metaItems := make([]pluginsv0alpha1.PluginMeta, 0, len(plugins.Items)) + // Convert each Plugin to Meta + metaItems := make([]pluginsv0alpha1.Meta, 0, len(plugins.Items)) for _, plugin := range plugins.Items { result, err := s.metaManager.GetMeta(ctx, plugin.Spec.Id, plugin.Spec.Version) if err != nil { @@ -121,14 +121,25 @@ func (s *PluginMetaStorage) List(ctx context.Context, options *internalversion.L continue } - pluginMeta := createPluginMetaFromPluginMetaJSONData(result.Meta, plugin.Name, plugin.Namespace) - metaItems = append(metaItems, *pluginMeta) + pluginMeta := pluginsv0alpha1.Meta{ + ObjectMeta: metav1.ObjectMeta{ + Name: plugin.Name, + Namespace: plugin.Namespace, + }, + Spec: result.Meta, + } + pluginMeta.SetGroupVersionKind(schema.GroupVersionKind{ + Group: pluginsv0alpha1.APIGroup, + Version: pluginsv0alpha1.APIVersion, + Kind: pluginsv0alpha1.MetaKind().Kind(), + }) + metaItems = append(metaItems, pluginMeta) } - list := &pluginsv0alpha1.PluginMetaList{ + list := &pluginsv0alpha1.MetaList{ TypeMeta: metav1.TypeMeta{ APIVersion: pluginsv0alpha1.APIGroup + "/" + pluginsv0alpha1.APIVersion, - Kind: pluginsv0alpha1.PluginMetaKind().Kind() + "List", + Kind: pluginsv0alpha1.MetaKind().Kind() + "List", }, Items: metaItems, } @@ -136,7 +147,7 @@ func (s *PluginMetaStorage) List(ctx context.Context, options *internalversion.L return list, nil } -func (s *PluginMetaStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { +func (s *MetaStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { ns, err := request.NamespaceInfoFrom(ctx, true) if err != nil { return nil, err @@ -169,27 +180,18 @@ func (s *PluginMetaStorage) Get(ctx context.Context, name string, options *metav return nil, apierrors.NewInternalError(fmt.Errorf("failed to fetch plugin metadata: %w", err)) } - return createPluginMetaFromPluginMetaJSONData(result.Meta, name, ns.Value), nil -} - -// createPluginMetaFromPluginMetaJSONData creates a PluginMeta k8s object from PluginMetaJSONData and plugin metadata. -func createPluginMetaFromPluginMetaJSONData(pluginJSON pluginsv0alpha1.PluginMetaJSONData, name, namespace string) *pluginsv0alpha1.PluginMeta { - pluginMeta := &pluginsv0alpha1.PluginMeta{ + pluginMeta := &pluginsv0alpha1.Meta{ ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: pluginsv0alpha1.PluginMetaSpec{ - PluginJSON: pluginJSON, + Name: plugin.Name, + Namespace: plugin.Namespace, }, + Spec: result.Meta, } - - // Set the GroupVersionKind pluginMeta.SetGroupVersionKind(schema.GroupVersionKind{ Group: pluginsv0alpha1.APIGroup, Version: pluginsv0alpha1.APIVersion, - Kind: pluginsv0alpha1.PluginMetaKind().Kind(), + Kind: pluginsv0alpha1.MetaKind().Kind(), }) - return pluginMeta + return pluginMeta, nil } diff --git a/apps/preferences/go.mod b/apps/preferences/go.mod index 661002a3b59..520609347ae 100644 --- a/apps/preferences/go.mod +++ b/apps/preferences/go.mod @@ -3,10 +3,10 @@ module github.com/grafana/grafana/apps/preferences go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 + github.com/grafana/grafana-app-sdk v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( @@ -17,19 +17,29 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.48.3 // indirect + github.com/google/gnostic-models v0.7.1 // indirect + github.com/grafana/grafana-app-sdk/logging v0.48.7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -40,29 +50,29 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.11.1 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/preferences/go.sum b/apps/preferences/go.sum index 75a19848d73..aa5de8cbe99 100644 --- a/apps/preferences/go.sum +++ b/apps/preferences/go.sum @@ -14,29 +14,55 @@ github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 h1:X0cnaFdR+iz+sDSuoZmkryFSjOirchHe2MdKSRwBWgM= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2/go.mod h1:RRvSjHH12/PnQaXraMO65jUhVu8n59mzvhfIMBETnV4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -58,8 +84,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -76,8 +102,6 @@ github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletI github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -85,10 +109,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -101,16 +125,16 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= @@ -126,24 +150,24 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -154,31 +178,31 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/provisioning/go.mod b/apps/provisioning/go.mod index 3cccd7dd8be..62f3f1bf49c 100644 --- a/apps/provisioning/go.mod +++ b/apps/provisioning/go.mod @@ -7,17 +7,18 @@ require ( github.com/google/go-github/v70 v70.0.0 github.com/google/uuid v1.6.0 github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana/apps/secret v0.0.0-20250902093454-b56b7add012f github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 github.com/grafana/nanogit v0.3.0 github.com/migueleliasweb/go-github-mock v1.1.0 github.com/stretchr/testify v1.11.1 - golang.org/x/oauth2 v0.33.0 - k8s.io/apimachinery v0.34.2 - k8s.io/apiserver v0.34.2 - k8s.io/client-go v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + golang.org/x/oauth2 v0.34.0 + k8s.io/apimachinery v0.34.3 + k8s.io/apiserver v0.34.3 + k8s.io/client-go v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e sigs.k8s.io/structured-merge-diff/v6 v6.3.1 ) @@ -28,64 +29,81 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-jose/go-jose/v3 v3.0.4 // indirect github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-github/v64 v64.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 // indirect github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect - github.com/grafana/grafana-app-sdk v0.48.5 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.18.0 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/objx v0.5.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.45.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/component-base v0.34.2 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/component-base v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/apps/provisioning/go.sum b/apps/provisioning/go.sum index 0e1ba180fad..8b5733639be 100644 --- a/apps/provisioning/go.sum +++ b/apps/provisioning/go.sum @@ -14,6 +14,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= @@ -23,22 +25,50 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= +github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -62,16 +92,21 @@ github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGr github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4/go.mod h1:qeWYbnWzaYGl88JlL9+DsP1GT2Cudm58rLtx13fKZdw= 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/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana/apps/secret v0.0.0-20250902093454-b56b7add012f h1:f+Z5Xpfp1WNYjUe23ginerWsHWUsRgOWrr3WGu3SlWs= github.com/grafana/grafana/apps/secret v0.0.0-20250902093454-b56b7add012f/go.mod h1:RA8mP8KVIwKXBx3Ssqa/uEBABib5LvUWYPVMxrNvnP0= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 h1:X0cnaFdR+iz+sDSuoZmkryFSjOirchHe2MdKSRwBWgM= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2/go.mod h1:RRvSjHH12/PnQaXraMO65jUhVu8n59mzvhfIMBETnV4= github.com/grafana/nanogit v0.3.0 h1:XNEef+4Vi+465ZITJs/g/xgnDRJbWhhJ7iQrAnWZ0oQ= github.com/grafana/nanogit v0.3.0/go.mod h1:6s6CCTpyMOHPpcUZaLGI+rgBEKdmxVbhqSGgCK13j7Y= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -86,8 +121,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/migueleliasweb/go-github-mock v1.1.0 h1:GKaOBPsrPGkAKgtfuWY8MclS1xR6MInkx1SexJucMwE= github.com/migueleliasweb/go-github-mock v1.1.0/go.mod h1:pYe/XlGs4BGMfRY4vmeixVsODHnVDDhJ9zoi0qzSMHc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -96,14 +131,22 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -113,10 +156,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -128,6 +171,10 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -135,16 +182,16 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= @@ -156,8 +203,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= @@ -170,17 +217,17 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -191,23 +238,23 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -216,48 +263,48 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= -k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ= -k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/component-base v0.34.3 h1:zsEgw6ELqK0XncCQomgO9DpUIzlrYuZYA0Cgo+JWpVk= +k8s.io/component-base v0.34.3/go.mod h1:5iIlD8wPfWE/xSHTRfbjuvUul2WZbI2nOUK65XL0E/c= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/provisioning/kinds/connection.cue b/apps/provisioning/kinds/connection.cue new file mode 100644 index 00000000000..23af1991c02 --- /dev/null +++ b/apps/provisioning/kinds/connection.cue @@ -0,0 +1,73 @@ +package repository + +connection: { + kind: "Connection" + pluralName: "Connections" + current: "v0alpha1" + validation: { + operations: [ + "CREATE", + "UPDATE", + ] + } + versions: { + "v0alpha1": { + codegen: { + ts: {enabled: false} + go: {enabled: true} + } + schema: { + #GitHubConnectionConfig: { + // App-level information + // GitHub App ID + appID: int + + // Installation-level information + // GitHub App installation ID + installationID: int + } + #BitbucketConnectionConfig: { + // The app clientID + clientID: string + } + #GitlabConnectionConfig: { + // The app clientID + clientID: string + } + #HealthStatus: { + // When not healthy, requests will not be executed + healthy: bool + // When the health was checked last time + checked?: int + // Summary messages (can be shown to users) + // Will only be populated when not healthy + message?: [...string] + } + spec: { + // The connection provider type + type: "github" | "bitbucket" | "gitlab" + // The connection URL + url: *"" | string + // GitHub connection configuration + // Only applicable when provider is "github" + github?: #GitHubConnectionConfig + // Bitbucket connection configuration + // Only applicable when provider is "bitbucket" + bitbucket?: #BitbucketConnectionConfig + // Gitlab connection configuration + // Only applicable when provider is "gitlab" + gitlab?: #GitlabConnectionConfig + } + status: { + // The generation of the spec last time reconciliation ran + observedGeneration?: int + // Connection state + state: "connected" | "disconnected" + // The connection health status + health: #HealthStatus + } + } + } + } +} + diff --git a/apps/provisioning/kinds/manifest.cue b/apps/provisioning/kinds/manifest.cue index 40ffa64d922..b0202cb47ce 100644 --- a/apps/provisioning/kinds/manifest.cue +++ b/apps/provisioning/kinds/manifest.cue @@ -1,9 +1,11 @@ package repository manifest: { - appName: "provisioning" - groupOverride: "provisioning.grafana.app" - kinds: [ + appName: "provisioning" + groupOverride: "provisioning.grafana.app" + preferredVersion: "v0alpha1" + kinds: [ repository, + connection ] -} \ No newline at end of file +} diff --git a/apps/provisioning/kinds/repository.cue b/apps/provisioning/kinds/repository.cue index ba36b4b962f..629d7a62885 100644 --- a/apps/provisioning/kinds/repository.cue +++ b/apps/provisioning/kinds/repository.cue @@ -80,10 +80,13 @@ repository: { // Enabled must be saved as true before any sync job will run enabled: bool // Where values should be saved - target: "unified" | "legacy" + target: "instance" | "folder" // When non-zero, the sync will run periodically intervalSeconds?: int } + #ConnectionInfo: { + name: string + } #HealthStatus: { // When not healthy, requests will not be executed healthy: bool @@ -152,6 +155,9 @@ repository: { // The repository on GitLab. // Mutually exclusive with local | github | git. gitlab?: #GitLabRepositoryConfig + // The connection the repository references. + // This means the Repository is interacting with git via a Connection. + connection?: #ConnectionInfo } status: { // The generation of the spec last time reconciliation ran @@ -168,4 +174,4 @@ repository: { } } } -} \ No newline at end of file +} diff --git a/apps/provisioning/pkg/apis/manifestdata/provisioning_manifest.go b/apps/provisioning/pkg/apis/manifestdata/provisioning_manifest.go new file mode 100644 index 00000000000..c13e0389c11 --- /dev/null +++ b/apps/provisioning/pkg/apis/manifestdata/provisioning_manifest.go @@ -0,0 +1,92 @@ +// +// This file is generated by grafana-app-sdk +// DO NOT EDIT +// + +package manifestdata + +import ( + "fmt" + "strings" + + "github.com/grafana/grafana-app-sdk/app" + "github.com/grafana/grafana-app-sdk/resource" + "k8s.io/apimachinery/pkg/runtime" +) + +var appManifestData = app.ManifestData{ + AppName: "provisioning", + Group: "provisioning.grafana.app", + PreferredVersion: "v0alpha1", + Versions: []app.ManifestVersion{}, +} + +func LocalManifest() app.Manifest { + return app.NewEmbeddedManifest(appManifestData) +} + +func RemoteManifest() app.Manifest { + return app.NewAPIServerManifest("provisioning") +} + +var kindVersionToGoType = map[string]resource.Kind{} + +// ManifestGoTypeAssociator returns the associated resource.Kind instance for a given Kind and Version, if one exists. +// If there is no association for the provided Kind and Version, exists will return false. +func ManifestGoTypeAssociator(kind, version string) (goType resource.Kind, exists bool) { + goType, exists = kindVersionToGoType[fmt.Sprintf("%s/%s", kind, version)] + return goType, exists +} + +var customRouteToGoResponseType = map[string]any{} + +// ManifestCustomRouteResponsesAssociator returns the associated response go type for a given kind, version, custom route path, and method, if one exists. +// kind may be empty for custom routes which are not kind subroutes. Leading slashes are removed from subroute paths. +// If there is no association for the provided kind, version, custom route path, and method, exists will return false. +// Resource routes (those without a kind) should prefix their route with "/" if the route is namespaced (otherwise the route is assumed to be cluster-scope) +func ManifestCustomRouteResponsesAssociator(kind, version, path, verb string) (goType any, exists bool) { + if len(path) > 0 && path[0] == '/' { + path = path[1:] + } + goType, exists = customRouteToGoResponseType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] + return goType, exists +} + +var customRouteToGoParamsType = map[string]runtime.Object{} + +func ManifestCustomRouteQueryAssociator(kind, version, path, verb string) (goType runtime.Object, exists bool) { + if len(path) > 0 && path[0] == '/' { + path = path[1:] + } + goType, exists = customRouteToGoParamsType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] + return goType, exists +} + +var customRouteToGoRequestBodyType = map[string]any{} + +func ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb string) (goType any, exists bool) { + if len(path) > 0 && path[0] == '/' { + path = path[1:] + } + goType, exists = customRouteToGoRequestBodyType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] + return goType, exists +} + +type GoTypeAssociator struct{} + +func NewGoTypeAssociator() *GoTypeAssociator { + return &GoTypeAssociator{} +} + +func (g *GoTypeAssociator) KindToGoType(kind, version string) (goType resource.Kind, exists bool) { + return ManifestGoTypeAssociator(kind, version) +} +func (g *GoTypeAssociator) CustomRouteReturnGoType(kind, version, path, verb string) (goType any, exists bool) { + return ManifestCustomRouteResponsesAssociator(kind, version, path, verb) +} +func (g *GoTypeAssociator) CustomRouteQueryGoType(kind, version, path, verb string) (goType runtime.Object, exists bool) { + return ManifestCustomRouteQueryAssociator(kind, version, path, verb) +} +func (g *GoTypeAssociator) CustomRouteRequestBodyGoType(kind, version, path, verb string) (goType any, exists bool) { + return ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb) +} diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/connections.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/connections.go new file mode 100644 index 00000000000..2738af49db1 --- /dev/null +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/connections.go @@ -0,0 +1,141 @@ +package v0alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +// When this code is changed, make sure to update the code generation. +// As of writing, this can be done via the hack dir in the root of the repo: ./hack/update-codegen.sh provisioning +// If you've opened the generated files in this dir at some point in VSCode, you may also have to re-open them to clear errors. +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type Connection struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ConnectionSpec `json:"spec,omitempty"` + Secure ConnectionSecure `json:"secure,omitzero,omitempty"` + Status ConnectionStatus `json:"status,omitempty"` +} + +type ConnectionSecure struct { + // PrivateKey is the reference to the private key used for GitHub App authentication. + // This value is stored securely and cannot be read back + PrivateKey common.InlineSecureValue `json:"privateKey,omitzero,omitempty"` + + // ClientSecret is the reference to the secret used for other providers authentication, + // and Github on-behalf-of authentication. + // This value is stored securely and cannot be read back + ClientSecret common.InlineSecureValue `json:"clientSecret,omitzero,omitempty"` + + // Token is the reference of the token used to act as the Connection. + // This value is stored securely and cannot be read back + Token common.InlineSecureValue `json:"token,omitzero,omitempty"` +} + +func (v ConnectionSecure) IsZero() bool { + return v.PrivateKey.IsZero() && v.Token.IsZero() +} + +type GitHubConnectionConfig struct { + // GitHub App ID + AppID string `json:"appID"` + + // GitHub App installation ID + InstallationID string `json:"installationID"` +} + +type BitbucketConnectionConfig struct { + // App client ID + ClientID string `json:"clientID"` +} + +type GitlabConnectionConfig struct { + // App client ID + ClientID string `json:"clientID"` +} + +// ConnectionType defines the types of Connection providers +// +enum +type ConnectionType string + +// ConnectionType values. +const ( + GithubConnectionType ConnectionType = "github" + GitlabConnectionType ConnectionType = "gitlab" + BitbucketConnectionType ConnectionType = "bitbucket" +) + +type ConnectionSpec struct { + // The connection provider type + Type ConnectionType `json:"type"` + // The connection URL + URL string `json:"url,omitempty"` + + // GitHub connection configuration + // Only applicable when provider is "github" + GitHub *GitHubConnectionConfig `json:"github,omitempty"` + // Bitbucket connection configuration + // Only applicable when provider is "bitbucket" + Bitbucket *BitbucketConnectionConfig `json:"bitbucket,omitempty"` + // Gitlab connection configuration + // Only applicable when provider is "gitlab" + Gitlab *GitlabConnectionConfig `json:"gitlab,omitempty"` +} + +// ConnectionState defines the state of a Connection +// +enum +type ConnectionState string + +// ConnectionState values +const ( + ConnectionStateConnected ConnectionState = "connected" + ConnectionStateDisconnected ConnectionState = "disconnected" +) + +// The status of a Connection. +// This is expected never to be created by a kubectl call or similar, and is expected to rarely (if ever) be edited manually. +type ConnectionStatus struct { + // The generation of the spec last time reconciliation ran + ObservedGeneration int64 `json:"observedGeneration"` + + // Connection state + State ConnectionState `json:"state"` + + // The connection health status + Health HealthStatus `json:"health"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type ConnectionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + // +listType=atomic + Items []Connection `json:"items"` +} + +// ExternalRepositoryList lists repositories from an external git provider +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type ExternalRepositoryList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + // +listType=atomic + Items []ExternalRepository `json:"items"` +} + +type ExternalRepository struct { + // Name of the repository + Name string `json:"name"` + // Owner is the user, organization, or workspace that owns the repository + // For GitHub: organization or user + // For GitLab: namespace (user or group) + // For Bitbucket: workspace + // For pure Git: empty + Owner string `json:"owner,omitempty"` + // URL of the repository + URL string `json:"url"` +} diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/health.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/health.go new file mode 100644 index 00000000000..1298580c9a9 --- /dev/null +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/health.go @@ -0,0 +1,26 @@ +package v0alpha1 + +// HealthFailureType represents different types of healthcheck failures +// +enum +type HealthFailureType string + +const ( + HealthFailureHook HealthFailureType = "hook" + HealthFailureHealth HealthFailureType = "health" +) + +type HealthStatus struct { + // When not healthy, requests will not be executed + Healthy bool `json:"healthy"` + + // The type of the error + Error HealthFailureType `json:"error,omitempty"` + + // When the health was checked last time + Checked int64 `json:"checked,omitempty"` + + // Summary messages (can be shown to users) + // Will only be populated when not healthy + // +listType=atomic + Message []string `json:"message,omitempty"` +} diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/jobs.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/jobs.go index b96fb1a6d27..100c75b080b 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/jobs.go +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/jobs.go @@ -136,9 +136,6 @@ type ExportJobOptions struct { } type MigrateJobOptions struct { - // Preserve history (if possible) - History bool `json:"history,omitempty"` - // Message to use when committing the changes in a single commit Message string `json:"message,omitempty"` } @@ -198,6 +195,7 @@ type JobStatus struct { Finished int64 `json:"finished,omitempty"` Message string `json:"message,omitempty"` Errors []string `json:"errors,omitempty"` + Warnings []string `json:"warnings,omitempty"` // Optional value 0-100 that can be set while running Progress float64 `json:"progress,omitempty"` @@ -225,18 +223,20 @@ type JobResourceSummary struct { Kind string `json:"kind,omitempty"` Total int64 `json:"total,omitempty"` // the count (if known) - Create int64 `json:"create,omitempty"` - Update int64 `json:"update,omitempty"` - Delete int64 `json:"delete,omitempty"` - Write int64 `json:"write,omitempty"` // Create or update (export) - Error int64 `json:"error,omitempty"` // The error count + Create int64 `json:"create,omitempty"` + Update int64 `json:"update,omitempty"` + Delete int64 `json:"delete,omitempty"` + Write int64 `json:"write,omitempty"` // Create or update (export) + Error int64 `json:"error,omitempty"` // The error count + Warning int64 `json:"warning,omitempty"` // The warning count // No action required (useful for sync) Noop int64 `json:"noop,omitempty"` - // Report errors for this resource type + // Report errors/warnings for this resource type // This may not be an exhaustive list and recommend looking at the logs for more info - Errors []string `json:"errors,omitempty"` + Errors []string `json:"errors,omitempty"` + Warnings []string `json:"warnings,omitempty"` } // HistoricJob is an append only log, saving all jobs that have been processed. diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/register.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/register.go index 777484828f6..c1785a048d1 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/register.go +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/register.go @@ -115,6 +115,47 @@ var HistoricJobResourceInfo = utils.NewResourceInfo(GROUP, VERSION, }, }) +var ConnectionResourceInfo = utils.NewResourceInfo(GROUP, VERSION, + "connections", "connection", "Connection", + func() runtime.Object { return &Connection{} }, // newObj + func() runtime.Object { return &ConnectionList{} }, // newList + utils.TableColumns{ // Returned by `kubectl get`. Doesn't affect disk storage. + Definition: []metav1.TableColumnDefinition{ + {Name: "Name", Type: "string", Format: "name"}, + {Name: "Created At", Type: "date"}, + {Name: "Type", Type: "string"}, + {Name: "AppID", Type: "string"}, + {Name: "InstallationID", Type: "string"}, + {Name: "ClientID", Type: "string"}, + }, + Reader: func(obj any) ([]interface{}, error) { + m, ok := obj.(*Connection) + if !ok { + return nil, errors.New("expected Repository") + } + + var appID, installationID, clientID string + switch m.Spec.Type { + case GithubConnectionType: + appID = m.Spec.GitHub.AppID + installationID = m.Spec.GitHub.InstallationID + case BitbucketConnectionType: + clientID = m.Spec.Bitbucket.ClientID + case GitlabConnectionType: + clientID = m.Spec.Gitlab.ClientID + } + + return []interface{}{ + m.Name, + m.CreationTimestamp.UTC().Format(time.RFC3339), + m.Spec.Type, + appID, + installationID, + clientID, + }, nil + }, + }) + var ( // SchemeGroupVersion is group version used to register these objects SchemeGroupVersion = schema.GroupVersion{Group: GROUP, Version: VERSION} @@ -154,6 +195,9 @@ func AddKnownTypes(gv schema.GroupVersion, scheme *runtime.Scheme) error { &RefList{}, &HistoricJob{}, &HistoricJobList{}, + &Connection{}, + &ConnectionList{}, + &ExternalRepositoryList{}, ) return nil } diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go index 3031bde77cb..1aab919c9f6 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/settings.go @@ -9,11 +9,6 @@ import ( type RepositoryViewList struct { metav1.TypeMeta `json:",inline"` - // The backend is using legacy storage - // FIXME: Not sure where this should be exposed... but we need it somewhere - // The UI should force the onboarding workflow when this is true - LegacyStorage bool `json:"legacyStorage,omitempty"` - // The valid targets (can disable instance or folder types) AllowedTargets []SyncTargetType `json:"allowedTargets,omitempty"` diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/types.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/types.go index dff7c3813e5..c2247e21809 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/types.go +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/types.go @@ -219,6 +219,10 @@ func (r *Repository) Path() string { return "" } +type ConnectionInfo struct { + Name string `json:"name"` +} + type RepositorySpec struct { // The repository display name (shown in the UI) Title string `json:"title"` @@ -256,6 +260,10 @@ type RepositorySpec struct { // The repository on GitLab. // Mutually exclusive with local | github | git. GitLab *GitLabRepositoryConfig `json:"gitlab,omitempty"` + + // The connection the repository references. + // This means the Repository is interacting with git via a Connection. + Connection *ConnectionInfo `json:"connection,omitempty"` } // SyncTargetType defines where we want all values to resolve @@ -315,31 +323,6 @@ type RepositoryStatus struct { DeleteError string `json:"deleteError,omitempty"` } -// HealthFailureType represents different types of repository failures -// +enum -type HealthFailureType string - -const ( - HealthFailureHook HealthFailureType = "hook" - HealthFailureHealth HealthFailureType = "health" -) - -type HealthStatus struct { - // When not healthy, requests will not be executed - Healthy bool `json:"healthy"` - - // The type of the error - Error HealthFailureType `json:"error,omitempty"` - - // When the health was checked last time - Checked int64 `json:"checked,omitempty"` - - // Summary messages (can be shown to users) - // Will only be populated when not healthy - // +listType=atomic - Message []string `json:"message,omitempty"` -} - type SyncStatus struct { // pending, running, success, error State JobState `json:"state"` diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go index 8a3def39e8d..97b1e752f68 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go @@ -27,6 +27,22 @@ func (in *Author) DeepCopy() *Author { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BitbucketConnectionConfig) DeepCopyInto(out *BitbucketConnectionConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BitbucketConnectionConfig. +func (in *BitbucketConnectionConfig) DeepCopy() *BitbucketConnectionConfig { + if in == nil { + return nil + } + out := new(BitbucketConnectionConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BitbucketRepositoryConfig) DeepCopyInto(out *BitbucketRepositoryConfig) { *out = *in @@ -43,6 +59,151 @@ func (in *BitbucketRepositoryConfig) DeepCopy() *BitbucketRepositoryConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Connection) DeepCopyInto(out *Connection) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Secure = in.Secure + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Connection. +func (in *Connection) DeepCopy() *Connection { + if in == nil { + return nil + } + out := new(Connection) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Connection) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionInfo) DeepCopyInto(out *ConnectionInfo) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionInfo. +func (in *ConnectionInfo) DeepCopy() *ConnectionInfo { + if in == nil { + return nil + } + out := new(ConnectionInfo) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionList) DeepCopyInto(out *ConnectionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Connection, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionList. +func (in *ConnectionList) DeepCopy() *ConnectionList { + if in == nil { + return nil + } + out := new(ConnectionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ConnectionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionSecure) DeepCopyInto(out *ConnectionSecure) { + *out = *in + out.PrivateKey = in.PrivateKey + out.ClientSecret = in.ClientSecret + out.Token = in.Token + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionSecure. +func (in *ConnectionSecure) DeepCopy() *ConnectionSecure { + if in == nil { + return nil + } + out := new(ConnectionSecure) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionSpec) DeepCopyInto(out *ConnectionSpec) { + *out = *in + if in.GitHub != nil { + in, out := &in.GitHub, &out.GitHub + *out = new(GitHubConnectionConfig) + **out = **in + } + if in.Bitbucket != nil { + in, out := &in.Bitbucket, &out.Bitbucket + *out = new(BitbucketConnectionConfig) + **out = **in + } + if in.Gitlab != nil { + in, out := &in.Gitlab, &out.Gitlab + *out = new(GitlabConnectionConfig) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionSpec. +func (in *ConnectionSpec) DeepCopy() *ConnectionSpec { + if in == nil { + return nil + } + out := new(ConnectionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConnectionStatus) DeepCopyInto(out *ConnectionStatus) { + *out = *in + in.Health.DeepCopyInto(&out.Health) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionStatus. +func (in *ConnectionStatus) DeepCopy() *ConnectionStatus { + if in == nil { + return nil + } + out := new(ConnectionStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeleteJobOptions) DeepCopyInto(out *DeleteJobOptions) { *out = *in @@ -101,6 +262,53 @@ func (in *ExportJobOptions) DeepCopy() *ExportJobOptions { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalRepository) DeepCopyInto(out *ExternalRepository) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalRepository. +func (in *ExternalRepository) DeepCopy() *ExternalRepository { + if in == nil { + return nil + } + out := new(ExternalRepository) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalRepositoryList) DeepCopyInto(out *ExternalRepositoryList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ExternalRepository, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalRepositoryList. +func (in *ExternalRepositoryList) DeepCopy() *ExternalRepositoryList { + if in == nil { + return nil + } + out := new(ExternalRepositoryList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ExternalRepositoryList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FileItem) DeepCopyInto(out *FileItem) { *out = *in @@ -148,6 +356,22 @@ func (in *FileList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitHubConnectionConfig) DeepCopyInto(out *GitHubConnectionConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitHubConnectionConfig. +func (in *GitHubConnectionConfig) DeepCopy() *GitHubConnectionConfig { + if in == nil { + return nil + } + out := new(GitHubConnectionConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GitHubRepositoryConfig) DeepCopyInto(out *GitHubRepositoryConfig) { *out = *in @@ -196,6 +420,22 @@ func (in *GitRepositoryConfig) DeepCopy() *GitRepositoryConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GitlabConnectionConfig) DeepCopyInto(out *GitlabConnectionConfig) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitlabConnectionConfig. +func (in *GitlabConnectionConfig) DeepCopy() *GitlabConnectionConfig { + if in == nil { + return nil + } + out := new(GitlabConnectionConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HealthStatus) DeepCopyInto(out *HealthStatus) { *out = *in @@ -401,6 +641,11 @@ func (in *JobResourceSummary) DeepCopyInto(out *JobResourceSummary) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Warnings != nil { + in, out := &in.Warnings, &out.Warnings + *out = make([]string, len(*in)) + copy(*out, *in) + } return } @@ -468,6 +713,11 @@ func (in *JobStatus) DeepCopyInto(out *JobStatus) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Warnings != nil { + in, out := &in.Warnings, &out.Warnings + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.Summary != nil { in, out := &in.Summary, &out.Summary *out = make([]*JobResourceSummary, len(*in)) @@ -735,6 +985,11 @@ func (in *RepositorySpec) DeepCopyInto(out *RepositorySpec) { *out = new(GitLabRepositoryConfig) **out = **in } + if in.Connection != nil { + in, out := &in.Connection, &out.Connection + *out = new(ConnectionInfo) + **out = **in + } return } diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go b/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go index 9a4a99d703a..4db11489c98 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go @@ -15,15 +15,26 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.Author": schema_pkg_apis_provisioning_v0alpha1_Author(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.BitbucketConnectionConfig": schema_pkg_apis_provisioning_v0alpha1_BitbucketConnectionConfig(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.BitbucketRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_BitbucketRepositoryConfig(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.Connection": schema_pkg_apis_provisioning_v0alpha1_Connection(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionInfo": schema_pkg_apis_provisioning_v0alpha1_ConnectionInfo(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionList": schema_pkg_apis_provisioning_v0alpha1_ConnectionList(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionSecure": schema_pkg_apis_provisioning_v0alpha1_ConnectionSecure(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionSpec": schema_pkg_apis_provisioning_v0alpha1_ConnectionSpec(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionStatus": schema_pkg_apis_provisioning_v0alpha1_ConnectionStatus(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.DeleteJobOptions": schema_pkg_apis_provisioning_v0alpha1_DeleteJobOptions(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ErrorDetails": schema_pkg_apis_provisioning_v0alpha1_ErrorDetails(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ExportJobOptions": schema_pkg_apis_provisioning_v0alpha1_ExportJobOptions(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ExternalRepository": schema_pkg_apis_provisioning_v0alpha1_ExternalRepository(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ExternalRepositoryList": schema_pkg_apis_provisioning_v0alpha1_ExternalRepositoryList(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.FileItem": schema_pkg_apis_provisioning_v0alpha1_FileItem(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.FileList": schema_pkg_apis_provisioning_v0alpha1_FileList(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitHubConnectionConfig": schema_pkg_apis_provisioning_v0alpha1_GitHubConnectionConfig(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitHubRepositoryConfig(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitLabRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitLabRepositoryConfig(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_GitRepositoryConfig(ref), + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitlabConnectionConfig": schema_pkg_apis_provisioning_v0alpha1_GitlabConnectionConfig(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.HealthStatus": schema_pkg_apis_provisioning_v0alpha1_HealthStatus(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.HistoricJob": schema_pkg_apis_provisioning_v0alpha1_HistoricJob(ref), "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.HistoricJobList": schema_pkg_apis_provisioning_v0alpha1_HistoricJobList(ref), @@ -100,6 +111,27 @@ func schema_pkg_apis_provisioning_v0alpha1_Author(ref common.ReferenceCallback) } } +func schema_pkg_apis_provisioning_v0alpha1_BitbucketConnectionConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "clientID": { + SchemaProps: spec.SchemaProps{ + Description: "App client ID", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"clientID"}, + }, + }, + } +} + func schema_pkg_apis_provisioning_v0alpha1_BitbucketRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -142,6 +174,256 @@ func schema_pkg_apis_provisioning_v0alpha1_BitbucketRepositoryConfig(ref common. } } +func schema_pkg_apis_provisioning_v0alpha1_Connection(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "When this code is changed, make sure to update the code generation. As of writing, this can be done via the hack dir in the root of the repo: ./hack/update-codegen.sh provisioning If you've opened the generated files in this dir at some point in VSCode, you may also have to re-open them to clear errors.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionSpec"), + }, + }, + "secure": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionSecure"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionStatus"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionSecure", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionSpec", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_provisioning_v0alpha1_ConnectionInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name"}, + }, + }, + } +} + +func schema_pkg_apis_provisioning_v0alpha1_ConnectionList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.Connection"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.Connection", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_provisioning_v0alpha1_ConnectionSecure(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "privateKey": { + SchemaProps: spec.SchemaProps{ + Description: "PrivateKey is the reference to the private key used for GitHub App authentication. This value is stored securely and cannot be read back", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.InlineSecureValue"), + }, + }, + "clientSecret": { + SchemaProps: spec.SchemaProps{ + Description: "ClientSecret is the reference to the secret used for other providers authentication, and Github on-behalf-of authentication. This value is stored securely and cannot be read back", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.InlineSecureValue"), + }, + }, + "token": { + SchemaProps: spec.SchemaProps{ + Description: "Token is the reference of the token used to act as the Connection. This value is stored securely and cannot be read back", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.InlineSecureValue"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.InlineSecureValue"}, + } +} + +func schema_pkg_apis_provisioning_v0alpha1_ConnectionSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "The connection provider type\n\nPossible enum values:\n - `\"bitbucket\"`\n - `\"github\"`\n - `\"gitlab\"`", + Default: "", + Type: []string{"string"}, + Format: "", + Enum: []interface{}{"bitbucket", "github", "gitlab"}, + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Description: "The connection URL", + Type: []string{"string"}, + Format: "", + }, + }, + "github": { + SchemaProps: spec.SchemaProps{ + Description: "GitHub connection configuration Only applicable when provider is \"github\"", + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitHubConnectionConfig"), + }, + }, + "bitbucket": { + SchemaProps: spec.SchemaProps{ + Description: "Bitbucket connection configuration Only applicable when provider is \"bitbucket\"", + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.BitbucketConnectionConfig"), + }, + }, + "gitlab": { + SchemaProps: spec.SchemaProps{ + Description: "Gitlab connection configuration Only applicable when provider is \"gitlab\"", + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitlabConnectionConfig"), + }, + }, + }, + Required: []string{"type"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.BitbucketConnectionConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitHubConnectionConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitlabConnectionConfig"}, + } +} + +func schema_pkg_apis_provisioning_v0alpha1_ConnectionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "The status of a Connection. This is expected never to be created by a kubectl call or similar, and is expected to rarely (if ever) be edited manually.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "observedGeneration": { + SchemaProps: spec.SchemaProps{ + Description: "The generation of the spec last time reconciliation ran", + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "state": { + SchemaProps: spec.SchemaProps{ + Description: "Connection state\n\nPossible enum values:\n - `\"connected\"`\n - `\"disconnected\"`", + Default: "", + Type: []string{"string"}, + Format: "", + Enum: []interface{}{"connected", "disconnected"}, + }, + }, + "health": { + SchemaProps: spec.SchemaProps{ + Description: "The connection health status", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.HealthStatus"), + }, + }, + }, + Required: []string{"observedGeneration", "state", "health"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.HealthStatus"}, + } +} + func schema_pkg_apis_provisioning_v0alpha1_DeleteJobOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -264,6 +546,96 @@ func schema_pkg_apis_provisioning_v0alpha1_ExportJobOptions(ref common.Reference } } +func schema_pkg_apis_provisioning_v0alpha1_ExternalRepository(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the repository", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "owner": { + SchemaProps: spec.SchemaProps{ + Description: "Owner is the user, organization, or workspace that owns the repository For GitHub: organization or user For GitLab: namespace (user or group) For Bitbucket: workspace For pure Git: empty", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Description: "URL of the repository", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "url"}, + }, + }, + } +} + +func schema_pkg_apis_provisioning_v0alpha1_ExternalRepositoryList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ExternalRepositoryList lists repositories from an external git provider", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ExternalRepository"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ExternalRepository", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + func schema_pkg_apis_provisioning_v0alpha1_FileItem(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -362,6 +734,35 @@ func schema_pkg_apis_provisioning_v0alpha1_FileList(ref common.ReferenceCallback } } +func schema_pkg_apis_provisioning_v0alpha1_GitHubConnectionConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "appID": { + SchemaProps: spec.SchemaProps{ + Description: "GitHub App ID", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "installationID": { + SchemaProps: spec.SchemaProps{ + Description: "GitHub App installation ID", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"appID", "installationID"}, + }, + }, + } +} + func schema_pkg_apis_provisioning_v0alpha1_GitHubRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -481,6 +882,27 @@ func schema_pkg_apis_provisioning_v0alpha1_GitRepositoryConfig(ref common.Refere } } +func schema_pkg_apis_provisioning_v0alpha1_GitlabConnectionConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "clientID": { + SchemaProps: spec.SchemaProps{ + Description: "App client ID", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"clientID"}, + }, + }, + } +} + func schema_pkg_apis_provisioning_v0alpha1_HealthStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -889,6 +1311,13 @@ func schema_pkg_apis_provisioning_v0alpha1_JobResourceSummary(ref common.Referen Format: "int64", }, }, + "warning": { + SchemaProps: spec.SchemaProps{ + Description: "The error count", + Type: []string{"integer"}, + Format: "int64", + }, + }, "noop": { SchemaProps: spec.SchemaProps{ Description: "No action required (useful for sync)", @@ -898,7 +1327,7 @@ func schema_pkg_apis_provisioning_v0alpha1_JobResourceSummary(ref common.Referen }, "errors": { SchemaProps: spec.SchemaProps{ - Description: "Report errors for this resource type This may not be an exhaustive list and recommend looking at the logs for more info", + Description: "Report errors/warnings for this resource type This may not be an exhaustive list and recommend looking at the logs for more info", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -911,6 +1340,20 @@ func schema_pkg_apis_provisioning_v0alpha1_JobResourceSummary(ref common.Referen }, }, }, + "warnings": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, @@ -1029,6 +1472,20 @@ func schema_pkg_apis_provisioning_v0alpha1_JobStatus(ref common.ReferenceCallbac }, }, }, + "warnings": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, "progress": { SchemaProps: spec.SchemaProps{ Description: "Optional value 0-100 that can be set while running", @@ -1130,13 +1587,6 @@ func schema_pkg_apis_provisioning_v0alpha1_MigrateJobOptions(ref common.Referenc SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ - "history": { - SchemaProps: spec.SchemaProps{ - Description: "Preserve history (if possible)", - Type: []string{"boolean"}, - Format: "", - }, - }, "message": { SchemaProps: spec.SchemaProps{ Description: "Message to use when committing the changes in a single commit", @@ -1524,12 +1974,18 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositorySpec(ref common.ReferenceCa Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitLabRepositoryConfig"), }, }, + "connection": { + SchemaProps: spec.SchemaProps{ + Description: "The connection the repository references. This means the Repository is interacting with git via a Connection.", + Ref: ref("github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionInfo"), + }, + }, }, Required: []string{"title", "workflows", "sync", "type"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.BitbucketRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitLabRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.SyncOptions"}, + "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.BitbucketRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.ConnectionInfo", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitHubRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitLabRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.GitRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1.SyncOptions"}, } } @@ -1748,13 +2204,6 @@ func schema_pkg_apis_provisioning_v0alpha1_RepositoryViewList(ref common.Referen Format: "", }, }, - "legacyStorage": { - SchemaProps: spec.SchemaProps{ - Description: "The backend is using legacy storage FIXME: Not sure where this should be exposed... but we need it somewhere The UI should force the onboarding workflow when this is true", - Type: []string{"boolean"}, - Format: "", - }, - }, "allowedTargets": { SchemaProps: spec.SchemaProps{ Description: "The valid targets (can disable instance or folder types)", diff --git a/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list b/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list index c67b1462a9e..72567e04b90 100644 --- a/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list +++ b/apps/provisioning/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list @@ -1,10 +1,14 @@ +API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,ConnectionList,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,DeleteJobOptions,Paths API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,DeleteJobOptions,Resources +API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,ExternalRepositoryList,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,FileList,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,HistoryList,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,JobResourceSummary,Errors +API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,JobResourceSummary,Warnings API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,JobStatus,Errors API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,JobStatus,Summary +API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,JobStatus,Warnings API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,ManagerStats,Stats API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,MoveJobOptions,Paths API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,MoveJobOptions,Resources @@ -18,6 +22,7 @@ API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioni API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,ResourceList,Items API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,TestResults,Errors API rule violation: list_type_missing,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,WebhookStatus,SubscribedEvents +API rule violation: names_match,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,ConnectionSpec,GitHub API rule violation: names_match,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,JobSpec,PullRequest API rule violation: names_match,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,JobStatus,URLs API rule violation: names_match,github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1,ManagerStats,Identity diff --git a/apps/provisioning/pkg/auth/access_checker.go b/apps/provisioning/pkg/auth/access_checker.go new file mode 100644 index 00000000000..841c5421f2a --- /dev/null +++ b/apps/provisioning/pkg/auth/access_checker.go @@ -0,0 +1,22 @@ +package auth + +import ( + "context" + + authlib "github.com/grafana/authlib/types" + "github.com/grafana/grafana/pkg/apimachinery/identity" +) + +//go:generate mockery --name AccessChecker --structname MockAccessChecker --inpackage --filename access_checker_mock.go --with-expecter + +// AccessChecker provides access control checks with optional role-based fallback. +type AccessChecker interface { + // Check performs an access check and returns nil if allowed, or an appropriate + // API error if denied. If req.Namespace is empty, it will be filled from the + // identity's namespace. + Check(ctx context.Context, req authlib.CheckRequest, folder string) error + + // WithFallbackRole returns an AccessChecker configured with the specified fallback role. + // Whether the fallback is actually applied depends on the implementation. + WithFallbackRole(role identity.RoleType) AccessChecker +} diff --git a/apps/provisioning/pkg/auth/access_checker_mock.go b/apps/provisioning/pkg/auth/access_checker_mock.go new file mode 100644 index 00000000000..d0f1cddd7fc --- /dev/null +++ b/apps/provisioning/pkg/auth/access_checker_mock.go @@ -0,0 +1,135 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package auth + +import ( + context "context" + + identity "github.com/grafana/grafana/pkg/apimachinery/identity" + mock "github.com/stretchr/testify/mock" + + types "github.com/grafana/authlib/types" +) + +// MockAccessChecker is an autogenerated mock type for the AccessChecker type +type MockAccessChecker struct { + mock.Mock +} + +type MockAccessChecker_Expecter struct { + mock *mock.Mock +} + +func (_m *MockAccessChecker) EXPECT() *MockAccessChecker_Expecter { + return &MockAccessChecker_Expecter{mock: &_m.Mock} +} + +// Check provides a mock function with given fields: ctx, req, folder +func (_m *MockAccessChecker) Check(ctx context.Context, req types.CheckRequest, folder string) error { + ret := _m.Called(ctx, req, folder) + + if len(ret) == 0 { + panic("no return value specified for Check") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, types.CheckRequest, string) error); ok { + r0 = rf(ctx, req, folder) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockAccessChecker_Check_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Check' +type MockAccessChecker_Check_Call struct { + *mock.Call +} + +// Check is a helper method to define mock.On call +// - ctx context.Context +// - req types.CheckRequest +// - folder string +func (_e *MockAccessChecker_Expecter) Check(ctx interface{}, req interface{}, folder interface{}) *MockAccessChecker_Check_Call { + return &MockAccessChecker_Check_Call{Call: _e.mock.On("Check", ctx, req, folder)} +} + +func (_c *MockAccessChecker_Check_Call) Run(run func(ctx context.Context, req types.CheckRequest, folder string)) *MockAccessChecker_Check_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(types.CheckRequest), args[2].(string)) + }) + return _c +} + +func (_c *MockAccessChecker_Check_Call) Return(_a0 error) *MockAccessChecker_Check_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccessChecker_Check_Call) RunAndReturn(run func(context.Context, types.CheckRequest, string) error) *MockAccessChecker_Check_Call { + _c.Call.Return(run) + return _c +} + +// WithFallbackRole provides a mock function with given fields: role +func (_m *MockAccessChecker) WithFallbackRole(role identity.RoleType) AccessChecker { + ret := _m.Called(role) + + if len(ret) == 0 { + panic("no return value specified for WithFallbackRole") + } + + var r0 AccessChecker + if rf, ok := ret.Get(0).(func(identity.RoleType) AccessChecker); ok { + r0 = rf(role) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(AccessChecker) + } + } + + return r0 +} + +// MockAccessChecker_WithFallbackRole_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WithFallbackRole' +type MockAccessChecker_WithFallbackRole_Call struct { + *mock.Call +} + +// WithFallbackRole is a helper method to define mock.On call +// - role identity.RoleType +func (_e *MockAccessChecker_Expecter) WithFallbackRole(role interface{}) *MockAccessChecker_WithFallbackRole_Call { + return &MockAccessChecker_WithFallbackRole_Call{Call: _e.mock.On("WithFallbackRole", role)} +} + +func (_c *MockAccessChecker_WithFallbackRole_Call) Run(run func(role identity.RoleType)) *MockAccessChecker_WithFallbackRole_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(identity.RoleType)) + }) + return _c +} + +func (_c *MockAccessChecker_WithFallbackRole_Call) Return(_a0 AccessChecker) *MockAccessChecker_WithFallbackRole_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockAccessChecker_WithFallbackRole_Call) RunAndReturn(run func(identity.RoleType) AccessChecker) *MockAccessChecker_WithFallbackRole_Call { + _c.Call.Return(run) + return _c +} + +// NewMockAccessChecker creates a new instance of MockAccessChecker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockAccessChecker(t interface { + mock.TestingT + Cleanup(func()) +}) *MockAccessChecker { + mock := &MockAccessChecker{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/apps/provisioning/pkg/auth/round_tripper.go b/apps/provisioning/pkg/auth/round_tripper.go index 0d2f1cb4ac4..f5da0d778f0 100644 --- a/apps/provisioning/pkg/auth/round_tripper.go +++ b/apps/provisioning/pkg/auth/round_tripper.go @@ -1,3 +1,4 @@ +// Package auth provides authentication utilities for the provisioning API. package auth import ( @@ -6,7 +7,6 @@ import ( "net/http" "github.com/grafana/authlib/authn" - "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" utilnet "k8s.io/apimachinery/pkg/util/net" ) @@ -15,29 +15,61 @@ type tokenExchanger interface { Exchange(ctx context.Context, req authn.TokenExchangeRequest) (*authn.TokenExchangeResponse, error) } -// RoundTripper injects an exchanged access token for the provisioning API into outgoing requests. -type RoundTripper struct { - client tokenExchanger - transport http.RoundTripper - audience string +// RoundTripperOption configures optional behavior for the RoundTripper. +type RoundTripperOption func(*RoundTripper) + +// ExtraAudience appends an additional audience to the token exchange request. +// +// This is primarily used by operators connecting to the multitenant aggregator, +// where the token must include both the target API server's audience (e.g., dashboards, +// folders) and the provisioning group audience. The provisioning group audience is +// required so that the token passes the enforceManagerProperties check, which prevents +// unauthorized updates to provisioned resources. +// +// Example: +// +// authrt.NewRoundTripper(client, rt, "dashboards.grafana.app", authrt.ExtraAudience("provisioning.grafana.app")) +func ExtraAudience(audience string) RoundTripperOption { + return func(rt *RoundTripper) { + rt.extraAudience = audience + } } -// NewRoundTripper constructs a RoundTripper that exchanges the provided token per request -// and forwards the request to the provided base transport. -func NewRoundTripper(tokenExchangeClient tokenExchanger, base http.RoundTripper, audience string) *RoundTripper { - return &RoundTripper{ +// RoundTripper is an http.RoundTripper that performs token exchange before each request. +// It exchanges the service's credentials for an access token scoped to the configured +// audience(s), then injects that token into the outgoing request's X-Access-Token header. +type RoundTripper struct { + client tokenExchanger + transport http.RoundTripper + audience string + extraAudience string +} + +// NewRoundTripper creates a RoundTripper that exchanges tokens for each outgoing request. +// +// Parameters: +// - tokenExchangeClient: the client used to exchange credentials for access tokens +// - base: the underlying transport to delegate requests to after token injection +// - audience: the primary audience for the token (typically the target API server's group) +// - opts: optional configuration (e.g., ExtraAudience to include additional audiences) +func NewRoundTripper(tokenExchangeClient tokenExchanger, base http.RoundTripper, audience string, opts ...RoundTripperOption) *RoundTripper { + rt := &RoundTripper{ client: tokenExchangeClient, transport: base, audience: audience, } + for _, opt := range opts { + opt(rt) + } + return rt } +// RoundTrip exchanges credentials for an access token and injects it into the request. +// The token is scoped to all configured audiences and the wildcard namespace ("*"). func (t *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - // when we want to write resources with the provisioning API, the audience needs to include provisioning - // so that it passes the check in enforceManagerProperties, which prevents others from updating provisioned resources audiences := []string{t.audience} - if t.audience != v0alpha1.GROUP { - audiences = append(audiences, v0alpha1.GROUP) + if t.extraAudience != "" && t.extraAudience != t.audience { + audiences = append(audiences, t.extraAudience) } tokenResponse, err := t.client.Exchange(req.Context(), authn.TokenExchangeRequest{ diff --git a/apps/provisioning/pkg/auth/round_tripper_test.go b/apps/provisioning/pkg/auth/round_tripper_test.go index e3ae4b7b3d4..c1b2b81e17f 100644 --- a/apps/provisioning/pkg/auth/round_tripper_test.go +++ b/apps/provisioning/pkg/auth/round_tripper_test.go @@ -71,16 +71,29 @@ func TestRoundTripper_AudiencesAndNamespace(t *testing.T) { tests := []struct { name string audience string + extraAudience string wantAudiences []string }{ { - name: "adds group when custom audience", + name: "uses only provided audience by default", audience: "example-audience", + wantAudiences: []string{"example-audience"}, + }, + { + name: "uses only group audience by default", + audience: v0alpha1.GROUP, + wantAudiences: []string{v0alpha1.GROUP}, + }, + { + name: "extra audience adds provisioning group", + audience: "example-audience", + extraAudience: v0alpha1.GROUP, wantAudiences: []string{"example-audience", v0alpha1.GROUP}, }, { - name: "no duplicate when group audience", + name: "extra audience no duplicate when same as primary", audience: v0alpha1.GROUP, + extraAudience: v0alpha1.GROUP, wantAudiences: []string{v0alpha1.GROUP}, }, } @@ -88,11 +101,15 @@ func TestRoundTripper_AudiencesAndNamespace(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fx := &fakeExchanger{resp: &authn.TokenExchangeResponse{Token: "abc123"}} + var opts []RoundTripperOption + if tt.extraAudience != "" { + opts = append(opts, ExtraAudience(tt.extraAudience)) + } tr := NewRoundTripper(fx, roundTripperFunc(func(_ *http.Request) (*http.Response, error) { rr := httptest.NewRecorder() rr.WriteHeader(http.StatusOK) return rr.Result(), nil - }), tt.audience) + }), tt.audience, opts...) req, _ := http.NewRequestWithContext(context.Background(), http.MethodGet, "http://example", nil) resp, err := tr.RoundTrip(req) diff --git a/apps/provisioning/pkg/auth/session_access_checker.go b/apps/provisioning/pkg/auth/session_access_checker.go new file mode 100644 index 00000000000..1bc6a1b7218 --- /dev/null +++ b/apps/provisioning/pkg/auth/session_access_checker.go @@ -0,0 +1,153 @@ +package auth + +import ( + "context" + "fmt" + "strings" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" + + authlib "github.com/grafana/authlib/types" + "github.com/grafana/grafana-app-sdk/logging" + "github.com/grafana/grafana/pkg/apimachinery/identity" +) + +// sessionAccessChecker implements AccessChecker using Grafana session identity. +type sessionAccessChecker struct { + inner authlib.AccessChecker + fallbackRole identity.RoleType +} + +// NewSessionAccessChecker creates an AccessChecker that gets identity from Grafana +// sessions via GetRequester(ctx). Supports optional role-based fallback via +// WithFallbackRole for backwards compatibility. +func NewSessionAccessChecker(inner authlib.AccessChecker) AccessChecker { + return &sessionAccessChecker{ + inner: inner, + fallbackRole: "", + } +} + +// WithFallbackRole returns a new AccessChecker with the specified fallback role. +func (c *sessionAccessChecker) WithFallbackRole(role identity.RoleType) AccessChecker { + return &sessionAccessChecker{ + inner: c.inner, + fallbackRole: role, + } +} + +// Check performs an access check with optional role-based fallback. +// Returns nil if access is allowed, or an appropriate API error if denied. +func (c *sessionAccessChecker) Check(ctx context.Context, req authlib.CheckRequest, folder string) error { + logger := logging.FromContext(ctx).With("logger", "sessionAccessChecker") + + // Get identity from Grafana session + requester, err := identity.GetRequester(ctx) + if err != nil { + logger.Debug("failed to get requester", + "resource", req.Resource, + "verb", req.Verb, + "error", err.Error(), + ) + return apierrors.NewUnauthorized(fmt.Sprintf("failed to get requester: %v", err)) + } + + logger.Debug("checking access", + "identityType", requester.GetIdentityType(), + "orgRole", requester.GetOrgRole(), + "namespace", requester.GetNamespace(), + "resource", req.Resource, + "verb", req.Verb, + "group", req.Group, + "name", req.Name, + "folder", folder, + "fallbackRole", c.fallbackRole, + ) + + // Fill in namespace from identity if not provided + if req.Namespace == "" { + req.Namespace = requester.GetNamespace() + } + + // Perform the access check + rsp, err := c.inner.Check(ctx, requester, req, folder) + + // Build the GroupResource for error messages + gr := schema.GroupResource{Group: req.Group, Resource: req.Resource} + + // No fallback configured, return result directly + if c.fallbackRole == "" { + if err != nil { + logger.Debug("access check error (no fallback)", + "resource", req.Resource, + "verb", req.Verb, + "error", err.Error(), + ) + return apierrors.NewForbidden(gr, req.Name, fmt.Errorf("%s.%s is forbidden: %w", req.Resource, req.Group, err)) + } + if !rsp.Allowed { + logger.Debug("access check denied (no fallback)", + "resource", req.Resource, + "verb", req.Verb, + "group", req.Group, + "allowed", rsp.Allowed, + ) + return apierrors.NewForbidden(gr, req.Name, fmt.Errorf("permission denied")) + } + logger.Debug("access allowed", + "resource", req.Resource, + "verb", req.Verb, + ) + return nil + } + + // Fallback is configured - apply fallback logic + if err != nil { + if requester.GetOrgRole().Includes(c.fallbackRole) { + logger.Debug("access allowed via role fallback (after error)", + "resource", req.Resource, + "verb", req.Verb, + "fallbackRole", c.fallbackRole, + "orgRole", requester.GetOrgRole(), + ) + return nil // Fallback succeeded + } + logger.Debug("access check error (fallback failed)", + "resource", req.Resource, + "verb", req.Verb, + "error", err.Error(), + "fallbackRole", c.fallbackRole, + "orgRole", requester.GetOrgRole(), + ) + return apierrors.NewForbidden(gr, req.Name, fmt.Errorf("%s.%s is forbidden: %w", req.Resource, req.Group, err)) + } + + if rsp.Allowed { + logger.Debug("access allowed", + "resource", req.Resource, + "verb", req.Verb, + ) + return nil + } + + // Fall back to role for backwards compatibility + if requester.GetOrgRole().Includes(c.fallbackRole) { + logger.Debug("access allowed via role fallback", + "resource", req.Resource, + "verb", req.Verb, + "fallbackRole", c.fallbackRole, + "orgRole", requester.GetOrgRole(), + ) + return nil // Fallback succeeded + } + + logger.Debug("access denied (fallback role not met)", + "resource", req.Resource, + "verb", req.Verb, + "group", req.Group, + "fallbackRole", c.fallbackRole, + "orgRole", requester.GetOrgRole(), + ) + return apierrors.NewForbidden(gr, req.Name, fmt.Errorf("%s role is required", strings.ToLower(string(c.fallbackRole)))) +} diff --git a/apps/provisioning/pkg/auth/session_access_checker_test.go b/apps/provisioning/pkg/auth/session_access_checker_test.go new file mode 100644 index 00000000000..1e99a6e46db --- /dev/null +++ b/apps/provisioning/pkg/auth/session_access_checker_test.go @@ -0,0 +1,244 @@ +package auth + +import ( + "context" + "errors" + "testing" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + + authlib "github.com/grafana/authlib/types" + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/services/user" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// mockRequester implements identity.Requester for testing. +type mockRequester struct { + identity.Requester + orgRole identity.RoleType + identityType authlib.IdentityType + namespace string +} + +func (m *mockRequester) GetOrgRole() identity.RoleType { + return m.orgRole +} + +func (m *mockRequester) GetIdentityType() authlib.IdentityType { + return m.identityType +} + +func (m *mockRequester) GetNamespace() string { + return m.namespace +} + +func TestSessionAccessChecker_Check(t *testing.T) { + ctx := context.Background() + req := authlib.CheckRequest{ + Verb: "get", + Group: "provisioning.grafana.app", + Resource: "repositories", + Name: "test-repo", + Namespace: "default", + } + + tests := []struct { + name string + fallbackRole identity.RoleType + innerResponse authlib.CheckResponse + innerErr error + requester *mockRequester + expectAllow bool + }{ + { + name: "allowed by checker", + fallbackRole: identity.RoleAdmin, + innerResponse: authlib.CheckResponse{Allowed: true}, + requester: &mockRequester{orgRole: identity.RoleViewer, identityType: authlib.TypeUser}, + expectAllow: true, + }, + { + name: "denied by checker, fallback to admin role succeeds", + fallbackRole: identity.RoleAdmin, + innerResponse: authlib.CheckResponse{Allowed: false}, + requester: &mockRequester{orgRole: identity.RoleAdmin, identityType: authlib.TypeUser}, + expectAllow: true, + }, + { + name: "denied by checker, fallback to admin role fails for viewer", + fallbackRole: identity.RoleAdmin, + innerResponse: authlib.CheckResponse{Allowed: false}, + requester: &mockRequester{orgRole: identity.RoleViewer, identityType: authlib.TypeUser}, + expectAllow: false, + }, + { + name: "error from checker, fallback to admin role succeeds", + fallbackRole: identity.RoleAdmin, + innerErr: errors.New("access check failed"), + requester: &mockRequester{orgRole: identity.RoleAdmin, identityType: authlib.TypeUser}, + expectAllow: true, + }, + { + name: "error from checker, fallback fails for viewer", + fallbackRole: identity.RoleAdmin, + innerErr: errors.New("access check failed"), + requester: &mockRequester{orgRole: identity.RoleViewer, identityType: authlib.TypeUser}, + expectAllow: false, + }, + { + name: "denied, editor fallback succeeds for editor", + fallbackRole: identity.RoleEditor, + innerResponse: authlib.CheckResponse{Allowed: false}, + requester: &mockRequester{orgRole: identity.RoleEditor, identityType: authlib.TypeUser}, + expectAllow: true, + }, + { + name: "denied, editor fallback fails for viewer", + fallbackRole: identity.RoleEditor, + innerResponse: authlib.CheckResponse{Allowed: false}, + requester: &mockRequester{orgRole: identity.RoleViewer, identityType: authlib.TypeUser}, + expectAllow: false, + }, + { + name: "no fallback configured, denied stays denied", + fallbackRole: "", // no fallback + innerResponse: authlib.CheckResponse{Allowed: false}, + requester: &mockRequester{orgRole: identity.RoleAdmin, identityType: authlib.TypeUser}, + expectAllow: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: tt.innerResponse, + err: tt.innerErr, + } + + checker := NewSessionAccessChecker(mock) + if tt.fallbackRole != "" { + checker = checker.WithFallbackRole(tt.fallbackRole) + } + + // Add requester to context + testCtx := identity.WithRequester(ctx, tt.requester) + + err := checker.Check(testCtx, req, "") + + if tt.expectAllow { + require.NoError(t, err) + } else { + require.Error(t, err) + assert.True(t, apierrors.IsForbidden(err), "expected Forbidden error, got: %v", err) + } + }) + } +} + +func TestSessionAccessChecker_NoRequester(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: true}, + } + + checker := NewSessionAccessChecker(mock) + err := checker.Check(context.Background(), authlib.CheckRequest{}, "") + + require.Error(t, err) + assert.True(t, apierrors.IsUnauthorized(err), "expected Unauthorized error") +} + +func TestSessionAccessChecker_WithFallbackRole_ImmutableOriginal(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: false}, + } + + original := NewSessionAccessChecker(mock) + withAdmin := original.WithFallbackRole(identity.RoleAdmin) + withEditor := original.WithFallbackRole(identity.RoleEditor) + + ctx := identity.WithRequester(context.Background(), &mockRequester{ + orgRole: identity.RoleEditor, + identityType: authlib.TypeUser, + }) + + req := authlib.CheckRequest{} + + // Original should deny (no fallback) + err := original.Check(ctx, req, "") + require.Error(t, err, "original should deny without fallback") + + // WithAdmin should deny for editor + err = withAdmin.Check(ctx, req, "") + require.Error(t, err, "admin fallback should deny for editor") + + // WithEditor should allow for editor + err = withEditor.Check(ctx, req, "") + require.NoError(t, err, "editor fallback should allow for editor") +} + +func TestSessionAccessChecker_WithFallbackRole_ChainedCalls(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: false}, + } + + // Ensure chained WithFallbackRole calls work correctly + checker := NewSessionAccessChecker(mock). + WithFallbackRole(identity.RoleAdmin). + WithFallbackRole(identity.RoleEditor) // This should override admin + + ctx := identity.WithRequester(context.Background(), &mockRequester{ + orgRole: identity.RoleEditor, + identityType: authlib.TypeUser, + }) + + err := checker.Check(ctx, authlib.CheckRequest{}, "") + require.NoError(t, err, "last fallback (editor) should be used") +} + +func TestSessionAccessChecker_RealSignedInUser(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: false}, + } + + checker := NewSessionAccessChecker(mock).WithFallbackRole(identity.RoleAdmin) + + // Use a real SignedInUser + signedInUser := &user.SignedInUser{ + UserID: 1, + OrgID: 1, + OrgRole: identity.RoleAdmin, + } + + ctx := identity.WithRequester(context.Background(), signedInUser) + + err := checker.Check(ctx, authlib.CheckRequest{}, "") + require.NoError(t, err, "admin user should be allowed via fallback") +} + +func TestSessionAccessChecker_FillsNamespace(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: true}, + } + + checker := NewSessionAccessChecker(mock) + + ctx := identity.WithRequester(context.Background(), &mockRequester{ + orgRole: identity.RoleAdmin, + identityType: authlib.TypeUser, + namespace: "org-123", + }) + + // Request without namespace + req := authlib.CheckRequest{ + Verb: "get", + Group: "provisioning.grafana.app", + Resource: "repositories", + Name: "test-repo", + // Namespace intentionally empty + } + + err := checker.Check(ctx, req, "") + require.NoError(t, err) +} diff --git a/apps/provisioning/pkg/auth/token_access_checker.go b/apps/provisioning/pkg/auth/token_access_checker.go new file mode 100644 index 00000000000..8df833d7a34 --- /dev/null +++ b/apps/provisioning/pkg/auth/token_access_checker.go @@ -0,0 +1,92 @@ +package auth + +import ( + "context" + "fmt" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" + + authlib "github.com/grafana/authlib/types" + "github.com/grafana/grafana-app-sdk/logging" + "github.com/grafana/grafana/pkg/apimachinery/identity" +) + +// tokenAccessChecker implements AccessChecker using access tokens from context. +type tokenAccessChecker struct { + inner authlib.AccessChecker +} + +// NewTokenAccessChecker creates an AccessChecker that gets identity from access tokens +// via AuthInfoFrom(ctx). Role-based fallback is not supported. +func NewTokenAccessChecker(inner authlib.AccessChecker) AccessChecker { + return &tokenAccessChecker{inner: inner} +} + +// WithFallbackRole returns the same checker since fallback is not supported. +func (c *tokenAccessChecker) WithFallbackRole(_ identity.RoleType) AccessChecker { + return c +} + +// Check performs an access check using AuthInfo from context. +// Returns nil if access is allowed, or an appropriate API error if denied. +func (c *tokenAccessChecker) Check(ctx context.Context, req authlib.CheckRequest, folder string) error { + logger := logging.FromContext(ctx).With("logger", "tokenAccessChecker") + + // Get identity from access token in context + id, ok := authlib.AuthInfoFrom(ctx) + if !ok { + logger.Debug("no auth info in context", + "resource", req.Resource, + "verb", req.Verb, + "namespace", req.Namespace, + ) + return apierrors.NewUnauthorized("no auth info in context") + } + + logger.Debug("checking access", + "identityType", id.GetIdentityType(), + "namespace", id.GetNamespace(), + "resource", req.Resource, + "verb", req.Verb, + "group", req.Group, + "name", req.Name, + "folder", folder, + ) + + // Fill in namespace from identity if not provided + if req.Namespace == "" { + req.Namespace = id.GetNamespace() + } + + // Perform the access check + rsp, err := c.inner.Check(ctx, id, req, folder) + + // Build the GroupResource for error messages + gr := schema.GroupResource{Group: req.Group, Resource: req.Resource} + + if err != nil { + logger.Debug("access check error", + "resource", req.Resource, + "verb", req.Verb, + "error", err.Error(), + ) + return apierrors.NewForbidden(gr, req.Name, fmt.Errorf("%s.%s is forbidden: %w", req.Resource, req.Group, err)) + } + if !rsp.Allowed { + logger.Debug("access check denied", + "resource", req.Resource, + "verb", req.Verb, + "group", req.Group, + "identityType", id.GetIdentityType(), + "allowed", rsp.Allowed, + ) + return apierrors.NewForbidden(gr, req.Name, fmt.Errorf("permission denied")) + } + + logger.Debug("access allowed", + "resource", req.Resource, + "verb", req.Verb, + ) + return nil +} diff --git a/apps/provisioning/pkg/auth/token_access_checker_test.go b/apps/provisioning/pkg/auth/token_access_checker_test.go new file mode 100644 index 00000000000..bce0d3a77a0 --- /dev/null +++ b/apps/provisioning/pkg/auth/token_access_checker_test.go @@ -0,0 +1,137 @@ +package auth + +import ( + "context" + "errors" + "testing" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + + authlib "github.com/grafana/authlib/types" + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTokenAccessChecker_Check(t *testing.T) { + req := authlib.CheckRequest{ + Verb: "get", + Group: "provisioning.grafana.app", + Resource: "repositories", + Name: "test-repo", + Namespace: "default", + } + + tests := []struct { + name string + innerResponse authlib.CheckResponse + innerErr error + authInfo *identity.StaticRequester + expectAllow bool + }{ + { + name: "allowed by checker", + innerResponse: authlib.CheckResponse{Allowed: true}, + authInfo: &identity.StaticRequester{Type: authlib.TypeUser}, + expectAllow: true, + }, + { + name: "denied by checker", + innerResponse: authlib.CheckResponse{Allowed: false}, + authInfo: &identity.StaticRequester{Type: authlib.TypeUser}, + expectAllow: false, + }, + { + name: "error from checker", + innerErr: errors.New("access check failed"), + authInfo: &identity.StaticRequester{Type: authlib.TypeUser}, + expectAllow: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: tt.innerResponse, + err: tt.innerErr, + } + + checker := NewTokenAccessChecker(mock) + + // Add auth info to context + testCtx := authlib.WithAuthInfo(context.Background(), tt.authInfo) + + err := checker.Check(testCtx, req, "") + + if tt.expectAllow { + require.NoError(t, err) + } else { + require.Error(t, err) + assert.True(t, apierrors.IsForbidden(err), "expected Forbidden error, got: %v", err) + } + }) + } +} + +func TestTokenAccessChecker_NoAuthInfo(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: true}, + } + + checker := NewTokenAccessChecker(mock) + err := checker.Check(context.Background(), authlib.CheckRequest{}, "") + + require.Error(t, err) + assert.True(t, apierrors.IsUnauthorized(err), "expected Unauthorized error") +} + +func TestTokenAccessChecker_WithFallbackRole_IsNoOp(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: false}, + } + + checker := NewTokenAccessChecker(mock) + checkerWithFallback := checker.WithFallbackRole(identity.RoleAdmin) + + // They should be the same instance + assert.Same(t, checker, checkerWithFallback, "WithFallbackRole should return same instance") +} + +func TestTokenAccessChecker_FillsNamespace(t *testing.T) { + mock := &mockInnerAccessChecker{ + response: authlib.CheckResponse{Allowed: true}, + } + + checker := NewTokenAccessChecker(mock) + + ctx := authlib.WithAuthInfo(context.Background(), &identity.StaticRequester{ + Type: authlib.TypeUser, + Namespace: "org-123", + }) + + // Request without namespace + req := authlib.CheckRequest{ + Verb: "get", + Group: "provisioning.grafana.app", + Resource: "repositories", + Name: "test-repo", + // Namespace intentionally empty + } + + err := checker.Check(ctx, req, "") + require.NoError(t, err) +} + +// mockInnerAccessChecker implements authlib.AccessChecker for testing. +type mockInnerAccessChecker struct { + response authlib.CheckResponse + err error +} + +func (m *mockInnerAccessChecker) Check(_ context.Context, _ authlib.AuthInfo, _ authlib.CheckRequest, _ string) (authlib.CheckResponse, error) { + return m.response, m.err +} + +func (m *mockInnerAccessChecker) Compile(_ context.Context, _ authlib.AuthInfo, _ authlib.ListRequest) (authlib.ItemChecker, authlib.Zookie, error) { + return nil, nil, nil +} diff --git a/apps/provisioning/pkg/connection/connection.go b/apps/provisioning/pkg/connection/connection.go new file mode 100644 index 00000000000..d2043b5af4a --- /dev/null +++ b/apps/provisioning/pkg/connection/connection.go @@ -0,0 +1,16 @@ +package connection + +import ( + "context" +) + +//go:generate mockery --name Connection --structname MockConnection --inpackage --filename connection_mock.go --with-expecter +type Connection interface { + // Validate ensures the resource _looks_ correct. + // It should be called before trying to upsert a resource into the Kubernetes API server. + // This is not an indication that the connection information works, just that they are reasonably configured. + Validate(ctx context.Context) error + + // Mutate performs in place mutation of the underneath resource. + Mutate(context.Context) error +} diff --git a/apps/provisioning/pkg/connection/connection_mock.go b/apps/provisioning/pkg/connection/connection_mock.go new file mode 100644 index 00000000000..3867059d432 --- /dev/null +++ b/apps/provisioning/pkg/connection/connection_mock.go @@ -0,0 +1,128 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package connection + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// MockConnection is an autogenerated mock type for the Connection type +type MockConnection struct { + mock.Mock +} + +type MockConnection_Expecter struct { + mock *mock.Mock +} + +func (_m *MockConnection) EXPECT() *MockConnection_Expecter { + return &MockConnection_Expecter{mock: &_m.Mock} +} + +// Mutate provides a mock function with given fields: _a0 +func (_m *MockConnection) Mutate(_a0 context.Context) error { + ret := _m.Called(_a0) + + if len(ret) == 0 { + panic("no return value specified for Mutate") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockConnection_Mutate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Mutate' +type MockConnection_Mutate_Call struct { + *mock.Call +} + +// Mutate is a helper method to define mock.On call +// - _a0 context.Context +func (_e *MockConnection_Expecter) Mutate(_a0 interface{}) *MockConnection_Mutate_Call { + return &MockConnection_Mutate_Call{Call: _e.mock.On("Mutate", _a0)} +} + +func (_c *MockConnection_Mutate_Call) Run(run func(_a0 context.Context)) *MockConnection_Mutate_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockConnection_Mutate_Call) Return(_a0 error) *MockConnection_Mutate_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockConnection_Mutate_Call) RunAndReturn(run func(context.Context) error) *MockConnection_Mutate_Call { + _c.Call.Return(run) + return _c +} + +// Validate provides a mock function with given fields: ctx +func (_m *MockConnection) Validate(ctx context.Context) error { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for Validate") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// MockConnection_Validate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Validate' +type MockConnection_Validate_Call struct { + *mock.Call +} + +// Validate is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockConnection_Expecter) Validate(ctx interface{}) *MockConnection_Validate_Call { + return &MockConnection_Validate_Call{Call: _e.mock.On("Validate", ctx)} +} + +func (_c *MockConnection_Validate_Call) Run(run func(ctx context.Context)) *MockConnection_Validate_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockConnection_Validate_Call) Return(_a0 error) *MockConnection_Validate_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockConnection_Validate_Call) RunAndReturn(run func(context.Context) error) *MockConnection_Validate_Call { + _c.Call.Return(run) + return _c +} + +// NewMockConnection creates a new instance of MockConnection. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockConnection(t interface { + mock.TestingT + Cleanup(func()) +}) *MockConnection { + mock := &MockConnection{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/apps/provisioning/pkg/connection/extra_mock.go b/apps/provisioning/pkg/connection/extra_mock.go new file mode 100644 index 00000000000..cc2a1f3d5e2 --- /dev/null +++ b/apps/provisioning/pkg/connection/extra_mock.go @@ -0,0 +1,141 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package connection + +import ( + context "context" + + v0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + mock "github.com/stretchr/testify/mock" +) + +// MockExtra is an autogenerated mock type for the Extra type +type MockExtra struct { + mock.Mock +} + +type MockExtra_Expecter struct { + mock *mock.Mock +} + +func (_m *MockExtra) EXPECT() *MockExtra_Expecter { + return &MockExtra_Expecter{mock: &_m.Mock} +} + +// Build provides a mock function with given fields: ctx, r +func (_m *MockExtra) Build(ctx context.Context, r *v0alpha1.Connection) (Connection, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for Build") + } + + var r0 Connection + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Connection) (Connection, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Connection) Connection); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(Connection) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v0alpha1.Connection) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockExtra_Build_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Build' +type MockExtra_Build_Call struct { + *mock.Call +} + +// Build is a helper method to define mock.On call +// - ctx context.Context +// - r *v0alpha1.Connection +func (_e *MockExtra_Expecter) Build(ctx interface{}, r interface{}) *MockExtra_Build_Call { + return &MockExtra_Build_Call{Call: _e.mock.On("Build", ctx, r)} +} + +func (_c *MockExtra_Build_Call) Run(run func(ctx context.Context, r *v0alpha1.Connection)) *MockExtra_Build_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*v0alpha1.Connection)) + }) + return _c +} + +func (_c *MockExtra_Build_Call) Return(_a0 Connection, _a1 error) *MockExtra_Build_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockExtra_Build_Call) RunAndReturn(run func(context.Context, *v0alpha1.Connection) (Connection, error)) *MockExtra_Build_Call { + _c.Call.Return(run) + return _c +} + +// Type provides a mock function with no fields +func (_m *MockExtra) Type() v0alpha1.ConnectionType { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Type") + } + + var r0 v0alpha1.ConnectionType + if rf, ok := ret.Get(0).(func() v0alpha1.ConnectionType); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(v0alpha1.ConnectionType) + } + + return r0 +} + +// MockExtra_Type_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Type' +type MockExtra_Type_Call struct { + *mock.Call +} + +// Type is a helper method to define mock.On call +func (_e *MockExtra_Expecter) Type() *MockExtra_Type_Call { + return &MockExtra_Type_Call{Call: _e.mock.On("Type")} +} + +func (_c *MockExtra_Type_Call) Run(run func()) *MockExtra_Type_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockExtra_Type_Call) Return(_a0 v0alpha1.ConnectionType) *MockExtra_Type_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockExtra_Type_Call) RunAndReturn(run func() v0alpha1.ConnectionType) *MockExtra_Type_Call { + _c.Call.Return(run) + return _c +} + +// NewMockExtra creates a new instance of MockExtra. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockExtra(t interface { + mock.TestingT + Cleanup(func()) +}) *MockExtra { + mock := &MockExtra{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/apps/provisioning/pkg/connection/factory.go b/apps/provisioning/pkg/connection/factory.go new file mode 100644 index 00000000000..4a0e46d84d2 --- /dev/null +++ b/apps/provisioning/pkg/connection/factory.go @@ -0,0 +1,75 @@ +package connection + +import ( + "context" + "fmt" + "sort" + + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" +) + +//go:generate mockery --name=Extra --structname=MockExtra --inpackage --filename=extra_mock.go --with-expecter +type Extra interface { + Type() provisioning.ConnectionType + Build(ctx context.Context, r *provisioning.Connection) (Connection, error) +} + +//go:generate mockery --name=Factory --structname=MockFactory --inpackage --filename=factory_mock.go --with-expecter +type Factory interface { + Types() []provisioning.ConnectionType + Build(ctx context.Context, r *provisioning.Connection) (Connection, error) +} + +type factory struct { + extras map[provisioning.ConnectionType]Extra + enabled map[provisioning.ConnectionType]struct{} +} + +func ProvideFactory(enabled map[provisioning.ConnectionType]struct{}, extras []Extra) (Factory, error) { + f := &factory{ + enabled: enabled, + extras: make(map[provisioning.ConnectionType]Extra, len(extras)), + } + + for _, e := range extras { + if _, exists := f.extras[e.Type()]; exists { + return nil, fmt.Errorf("connection type %q is already registered", e.Type()) + } + f.extras[e.Type()] = e + } + + return f, nil +} + +func (f *factory) Types() []provisioning.ConnectionType { + var types []provisioning.ConnectionType + for t := range f.enabled { + if _, exists := f.extras[t]; exists { + types = append(types, t) + } + } + + sort.Slice(types, func(i, j int) bool { + return string(types[i]) < string(types[j]) + }) + + return types +} + +func (f *factory) Build(ctx context.Context, c *provisioning.Connection) (Connection, error) { + for _, e := range f.extras { + if e.Type() == c.Spec.Type { + if _, enabled := f.enabled[e.Type()]; !enabled { + return nil, fmt.Errorf("connection type %q is not enabled", e.Type()) + } + + return e.Build(ctx, c) + } + } + + return nil, fmt.Errorf("connection type %q is not supported", c.Spec.Type) +} + +var ( + _ Factory = (*factory)(nil) +) diff --git a/apps/provisioning/pkg/connection/factory_mock.go b/apps/provisioning/pkg/connection/factory_mock.go new file mode 100644 index 00000000000..8fd7023920f --- /dev/null +++ b/apps/provisioning/pkg/connection/factory_mock.go @@ -0,0 +1,143 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package connection + +import ( + context "context" + + v0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + mock "github.com/stretchr/testify/mock" +) + +// MockFactory is an autogenerated mock type for the Factory type +type MockFactory struct { + mock.Mock +} + +type MockFactory_Expecter struct { + mock *mock.Mock +} + +func (_m *MockFactory) EXPECT() *MockFactory_Expecter { + return &MockFactory_Expecter{mock: &_m.Mock} +} + +// Build provides a mock function with given fields: ctx, r +func (_m *MockFactory) Build(ctx context.Context, r *v0alpha1.Connection) (Connection, error) { + ret := _m.Called(ctx, r) + + if len(ret) == 0 { + panic("no return value specified for Build") + } + + var r0 Connection + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Connection) (Connection, error)); ok { + return rf(ctx, r) + } + if rf, ok := ret.Get(0).(func(context.Context, *v0alpha1.Connection) Connection); ok { + r0 = rf(ctx, r) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(Connection) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *v0alpha1.Connection) error); ok { + r1 = rf(ctx, r) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockFactory_Build_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Build' +type MockFactory_Build_Call struct { + *mock.Call +} + +// Build is a helper method to define mock.On call +// - ctx context.Context +// - r *v0alpha1.Connection +func (_e *MockFactory_Expecter) Build(ctx interface{}, r interface{}) *MockFactory_Build_Call { + return &MockFactory_Build_Call{Call: _e.mock.On("Build", ctx, r)} +} + +func (_c *MockFactory_Build_Call) Run(run func(ctx context.Context, r *v0alpha1.Connection)) *MockFactory_Build_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(*v0alpha1.Connection)) + }) + return _c +} + +func (_c *MockFactory_Build_Call) Return(_a0 Connection, _a1 error) *MockFactory_Build_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockFactory_Build_Call) RunAndReturn(run func(context.Context, *v0alpha1.Connection) (Connection, error)) *MockFactory_Build_Call { + _c.Call.Return(run) + return _c +} + +// Types provides a mock function with no fields +func (_m *MockFactory) Types() []v0alpha1.ConnectionType { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Types") + } + + var r0 []v0alpha1.ConnectionType + if rf, ok := ret.Get(0).(func() []v0alpha1.ConnectionType); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]v0alpha1.ConnectionType) + } + } + + return r0 +} + +// MockFactory_Types_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Types' +type MockFactory_Types_Call struct { + *mock.Call +} + +// Types is a helper method to define mock.On call +func (_e *MockFactory_Expecter) Types() *MockFactory_Types_Call { + return &MockFactory_Types_Call{Call: _e.mock.On("Types")} +} + +func (_c *MockFactory_Types_Call) Run(run func()) *MockFactory_Types_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockFactory_Types_Call) Return(_a0 []v0alpha1.ConnectionType) *MockFactory_Types_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockFactory_Types_Call) RunAndReturn(run func() []v0alpha1.ConnectionType) *MockFactory_Types_Call { + _c.Call.Return(run) + return _c +} + +// NewMockFactory creates a new instance of MockFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockFactory(t interface { + mock.TestingT + Cleanup(func()) +}) *MockFactory { + mock := &MockFactory{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/apps/provisioning/pkg/connection/factory_test.go b/apps/provisioning/pkg/connection/factory_test.go new file mode 100644 index 00000000000..4ce6bc96e0e --- /dev/null +++ b/apps/provisioning/pkg/connection/factory_test.go @@ -0,0 +1,309 @@ +package connection + +import ( + "context" + "errors" + "testing" + + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestProvideFactory(t *testing.T) { + t.Run("should create factory with valid extras", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + extra2 := NewMockExtra(t) + extra2.EXPECT().Type().Return(provisioning.GitlabConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + provisioning.GitlabConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra1, extra2}) + require.NoError(t, err) + require.NotNil(t, factory) + }) + + t.Run("should create factory with empty extras", func(t *testing.T) { + enabled := map[provisioning.ConnectionType]struct{}{} + + factory, err := ProvideFactory(enabled, []Extra{}) + require.NoError(t, err) + require.NotNil(t, factory) + }) + + t.Run("should create factory with nil enabled map", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + factory, err := ProvideFactory(nil, []Extra{extra1}) + require.NoError(t, err) + require.NotNil(t, factory) + }) + + t.Run("should return error when duplicate repository types", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + extra2 := NewMockExtra(t) + extra2.EXPECT().Type().Return(provisioning.GithubConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra1, extra2}) + require.Error(t, err) + assert.Nil(t, factory) + assert.Contains(t, err.Error(), "connection type \"github\" is already registered") + }) +} + +func TestFactory_Types(t *testing.T) { + t.Run("should return only enabled types that have extras", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + extra2 := NewMockExtra(t) + extra2.EXPECT().Type().Return(provisioning.GitlabConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + provisioning.GitlabConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra1, extra2}) + require.NoError(t, err) + + types := factory.Types() + assert.Len(t, types, 2) + assert.Contains(t, types, provisioning.GithubConnectionType) + assert.Contains(t, types, provisioning.GitlabConnectionType) + }) + + t.Run("should return sorted list of types", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GitlabConnectionType) + + extra2 := NewMockExtra(t) + extra2.EXPECT().Type().Return(provisioning.GithubConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + provisioning.GitlabConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra1, extra2}) + require.NoError(t, err) + + types := factory.Types() + assert.Len(t, types, 2) + // github should come before gitlab alphabetically + assert.Equal(t, provisioning.GithubConnectionType, types[0]) + assert.Equal(t, provisioning.GitlabConnectionType, types[1]) + }) + + t.Run("should return empty list when no types are enabled", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{} + + factory, err := ProvideFactory(enabled, []Extra{extra1}) + require.NoError(t, err) + + types := factory.Types() + assert.Empty(t, types) + }) + + t.Run("should not return types that are enabled but have no extras", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + provisioning.GitlabConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra1}) + require.NoError(t, err) + + types := factory.Types() + assert.Len(t, types, 1) + assert.Contains(t, types, provisioning.GithubConnectionType) + assert.NotContains(t, types, provisioning.GitlabConnectionType) + }) + + t.Run("should not return types that have extras but are not enabled", func(t *testing.T) { + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + extra2 := NewMockExtra(t) + extra2.EXPECT().Type().Return(provisioning.GitlabConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra1, extra2}) + require.NoError(t, err) + + types := factory.Types() + assert.Len(t, types, 1) + assert.Contains(t, types, provisioning.GithubConnectionType) + assert.NotContains(t, types, provisioning.GitlabConnectionType) + }) + + t.Run("should return empty list when no extras are provided", func(t *testing.T) { + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{}) + require.NoError(t, err) + + types := factory.Types() + assert.Empty(t, types) + }) +} + +func TestFactory_Build(t *testing.T) { + t.Run("should successfully build connection when type is enabled and has extra", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + }, + } + + mockConnection := NewMockConnection(t) + extra := NewMockExtra(t) + extra.EXPECT().Type().Return(provisioning.GithubConnectionType) + extra.EXPECT().Build(ctx, conn).Return(mockConnection, nil) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra}) + require.NoError(t, err) + + result, err := factory.Build(ctx, conn) + require.NoError(t, err) + assert.Equal(t, mockConnection, result) + }) + + t.Run("should return error when type is not enabled", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GitlabConnectionType, + }, + } + + extra := NewMockExtra(t) + extra.EXPECT().Type().Return(provisioning.GitlabConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra}) + require.NoError(t, err) + + result, err := factory.Build(ctx, conn) + require.Error(t, err) + assert.Nil(t, result) + assert.Contains(t, err.Error(), "connection type \"gitlab\" is not enabled") + }) + + t.Run("should return error when type is not supported", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GitlabConnectionType, + }, + } + + extra := NewMockExtra(t) + extra.EXPECT().Type().Return(provisioning.GithubConnectionType) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra}) + require.NoError(t, err) + + result, err := factory.Build(ctx, conn) + require.Error(t, err) + assert.Nil(t, result) + assert.Contains(t, err.Error(), "connection type \"gitlab\" is not supported") + }) + + t.Run("should pass through errors from extra.Build()", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + }, + } + + expectedErr := errors.New("build error") + extra := NewMockExtra(t) + extra.EXPECT().Type().Return(provisioning.GithubConnectionType) + extra.EXPECT().Build(ctx, conn).Return(nil, expectedErr) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra}) + require.NoError(t, err) + + result, err := factory.Build(ctx, conn) + require.Error(t, err) + assert.Nil(t, result) + assert.Equal(t, expectedErr, err) + }) + + t.Run("should build with multiple extras registered", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GitlabConnectionType, + }, + } + + mockConnection := NewMockConnection(t) + + extra1 := NewMockExtra(t) + extra1.EXPECT().Type().Return(provisioning.GithubConnectionType) + + extra2 := NewMockExtra(t) + extra2.EXPECT().Type().Return(provisioning.GitlabConnectionType) + extra2.EXPECT().Build(ctx, conn).Return(mockConnection, nil) + + enabled := map[provisioning.ConnectionType]struct{}{ + provisioning.GithubConnectionType: {}, + provisioning.GitlabConnectionType: {}, + } + + factory, err := ProvideFactory(enabled, []Extra{extra1, extra2}) + require.NoError(t, err) + + result, err := factory.Build(ctx, conn) + require.NoError(t, err) + assert.Equal(t, mockConnection, result) + }) +} diff --git a/apps/provisioning/pkg/connection/github/client.go b/apps/provisioning/pkg/connection/github/client.go new file mode 100644 index 00000000000..7ddb9a4665e --- /dev/null +++ b/apps/provisioning/pkg/connection/github/client.go @@ -0,0 +1,93 @@ +package github + +import ( + "context" + "errors" + "fmt" + "net/http" + "strconv" + + "github.com/google/go-github/v70/github" + apierrors "k8s.io/apimachinery/pkg/api/errors" +) + +// API errors that we need to convey after parsing real GH errors (or faking them). +var ( + //lint:ignore ST1005 this is not punctuation + ErrServiceUnavailable = apierrors.NewServiceUnavailable("github is unavailable") +) + +//go:generate mockery --name Client --structname MockClient --inpackage --filename client_mock.go --with-expecter +type Client interface { + // Apps and installations + GetApp(ctx context.Context) (App, error) + GetAppInstallation(ctx context.Context, installationID string) (AppInstallation, error) +} + +// App represents a Github App. +type App struct { + // ID represents the GH app ID. + ID int64 + // Slug represents the GH app slug. + Slug string + // Owner represents the GH account/org owning the app + Owner string +} + +// AppInstallation represents a Github App Installation. +type AppInstallation struct { + // ID represents the GH installation ID. + ID int64 + // Whether the installation is enabled or not. + Enabled bool +} + +type githubClient struct { + gh *github.Client +} + +func NewClient(client *github.Client) Client { + return &githubClient{client} +} + +// GetApp gets the app by using the given token. +func (r *githubClient) GetApp(ctx context.Context) (App, error) { + app, _, err := r.gh.Apps.Get(ctx, "") + if err != nil { + var ghErr *github.ErrorResponse + if errors.As(err, &ghErr) && ghErr.Response.StatusCode == http.StatusServiceUnavailable { + return App{}, ErrServiceUnavailable + } + return App{}, err + } + + // TODO(ferruvich): do we need any other info? + return App{ + ID: app.GetID(), + Slug: app.GetSlug(), + Owner: app.GetOwner().GetLogin(), + }, nil +} + +// GetAppInstallation gets the installation of the app related to the given token. +func (r *githubClient) GetAppInstallation(ctx context.Context, installationID string) (AppInstallation, error) { + id, err := strconv.Atoi(installationID) + if err != nil { + return AppInstallation{}, fmt.Errorf("invalid installation ID: %s", installationID) + } + + installation, _, err := r.gh.Apps.GetInstallation(ctx, int64(id)) + if err != nil { + var ghErr *github.ErrorResponse + if errors.As(err, &ghErr) && ghErr.Response.StatusCode == http.StatusServiceUnavailable { + return AppInstallation{}, ErrServiceUnavailable + } + return AppInstallation{}, err + } + + // TODO(ferruvich): do we need any other info? + return AppInstallation{ + ID: installation.GetID(), + Enabled: installation.GetSuspendedAt().IsZero(), + }, nil +} diff --git a/apps/provisioning/pkg/connection/github/client_mock.go b/apps/provisioning/pkg/connection/github/client_mock.go new file mode 100644 index 00000000000..c9f009f5021 --- /dev/null +++ b/apps/provisioning/pkg/connection/github/client_mock.go @@ -0,0 +1,149 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package github + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// MockClient is an autogenerated mock type for the Client type +type MockClient struct { + mock.Mock +} + +type MockClient_Expecter struct { + mock *mock.Mock +} + +func (_m *MockClient) EXPECT() *MockClient_Expecter { + return &MockClient_Expecter{mock: &_m.Mock} +} + +// GetApp provides a mock function with given fields: ctx +func (_m *MockClient) GetApp(ctx context.Context) (App, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetApp") + } + + var r0 App + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (App, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) App); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(App) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockClient_GetApp_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetApp' +type MockClient_GetApp_Call struct { + *mock.Call +} + +// GetApp is a helper method to define mock.On call +// - ctx context.Context +func (_e *MockClient_Expecter) GetApp(ctx interface{}) *MockClient_GetApp_Call { + return &MockClient_GetApp_Call{Call: _e.mock.On("GetApp", ctx)} +} + +func (_c *MockClient_GetApp_Call) Run(run func(ctx context.Context)) *MockClient_GetApp_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *MockClient_GetApp_Call) Return(_a0 App, _a1 error) *MockClient_GetApp_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockClient_GetApp_Call) RunAndReturn(run func(context.Context) (App, error)) *MockClient_GetApp_Call { + _c.Call.Return(run) + return _c +} + +// GetAppInstallation provides a mock function with given fields: ctx, installationID +func (_m *MockClient) GetAppInstallation(ctx context.Context, installationID string) (AppInstallation, error) { + ret := _m.Called(ctx, installationID) + + if len(ret) == 0 { + panic("no return value specified for GetAppInstallation") + } + + var r0 AppInstallation + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (AppInstallation, error)); ok { + return rf(ctx, installationID) + } + if rf, ok := ret.Get(0).(func(context.Context, string) AppInstallation); ok { + r0 = rf(ctx, installationID) + } else { + r0 = ret.Get(0).(AppInstallation) + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, installationID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockClient_GetAppInstallation_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAppInstallation' +type MockClient_GetAppInstallation_Call struct { + *mock.Call +} + +// GetAppInstallation is a helper method to define mock.On call +// - ctx context.Context +// - installationID string +func (_e *MockClient_Expecter) GetAppInstallation(ctx interface{}, installationID interface{}) *MockClient_GetAppInstallation_Call { + return &MockClient_GetAppInstallation_Call{Call: _e.mock.On("GetAppInstallation", ctx, installationID)} +} + +func (_c *MockClient_GetAppInstallation_Call) Run(run func(ctx context.Context, installationID string)) *MockClient_GetAppInstallation_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *MockClient_GetAppInstallation_Call) Return(_a0 AppInstallation, _a1 error) *MockClient_GetAppInstallation_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockClient_GetAppInstallation_Call) RunAndReturn(run func(context.Context, string) (AppInstallation, error)) *MockClient_GetAppInstallation_Call { + _c.Call.Return(run) + return _c +} + +// NewMockClient creates a new instance of MockClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockClient(t interface { + mock.TestingT + Cleanup(func()) +}) *MockClient { + mock := &MockClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/apps/provisioning/pkg/connection/github/client_test.go b/apps/provisioning/pkg/connection/github/client_test.go new file mode 100644 index 00000000000..bae6d6ac1e9 --- /dev/null +++ b/apps/provisioning/pkg/connection/github/client_test.go @@ -0,0 +1,297 @@ +package github_test + +import ( + "context" + "encoding/json" + "net/http" + "testing" + "time" + + "github.com/google/go-github/v70/github" + conngh "github.com/grafana/grafana/apps/provisioning/pkg/connection/github" + mockhub "github.com/migueleliasweb/go-github-mock/src/mock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGithubClient_GetApp(t *testing.T) { + tests := []struct { + name string + mockHandler *http.Client + token string + wantApp conngh.App + wantErr error + }{ + { + name: "get app successfully", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetApp, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + app := &github.App{ + ID: github.Ptr(int64(12345)), + Slug: github.Ptr("my-test-app"), + Owner: &github.User{ + Login: github.Ptr("grafana"), + }, + } + w.WriteHeader(http.StatusOK) + require.NoError(t, json.NewEncoder(w).Encode(app)) + }), + ), + ), + token: "test-token", + wantApp: conngh.App{ + ID: 12345, + Slug: "my-test-app", + Owner: "grafana", + }, + wantErr: nil, + }, + { + name: "service unavailable", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetApp, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusServiceUnavailable) + require.NoError(t, json.NewEncoder(w).Encode(github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusServiceUnavailable, + }, + Message: "Service unavailable", + })) + }), + ), + ), + token: "test-token", + wantApp: conngh.App{}, + wantErr: conngh.ErrServiceUnavailable, + }, + { + name: "other error", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetApp, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + require.NoError(t, json.NewEncoder(w).Encode(github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusInternalServerError, + }, + Message: "Internal server error", + })) + }), + ), + ), + token: "test-token", + wantApp: conngh.App{}, + wantErr: &github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusInternalServerError, + }, + Message: "Internal server error", + }, + }, + { + name: "unauthorized error", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetApp, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusUnauthorized) + require.NoError(t, json.NewEncoder(w).Encode(github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusUnauthorized, + }, + Message: "Bad credentials", + })) + }), + ), + ), + token: "invalid-token", + wantApp: conngh.App{}, + wantErr: &github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusUnauthorized, + }, + Message: "Bad credentials", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a mock client + ghClient := github.NewClient(tt.mockHandler) + client := conngh.NewClient(ghClient) + + // Call the method being tested + app, err := client.GetApp(context.Background()) + + // Check the error + if tt.wantErr != nil { + assert.Error(t, err) + assert.Equal(t, tt.wantApp, app) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantApp, app) + } + }) + } +} + +func TestGithubClient_GetAppInstallation(t *testing.T) { + tests := []struct { + name string + mockHandler *http.Client + appToken string + installationID string + wantInstallation conngh.AppInstallation + wantErr bool + errContains string + }{ + { + name: "get disabled app installation successfully", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetAppInstallationsByInstallationId, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + installation := &github.Installation{ + ID: github.Ptr(int64(67890)), + SuspendedAt: github.Ptr(github.Timestamp{Time: time.Now()}), + } + w.WriteHeader(http.StatusOK) + require.NoError(t, json.NewEncoder(w).Encode(installation)) + }), + ), + ), + appToken: "test-app-token", + installationID: "67890", + wantInstallation: conngh.AppInstallation{ + ID: 67890, + Enabled: false, + }, + wantErr: false, + }, + { + name: "get enabled app installation successfully", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetAppInstallationsByInstallationId, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + installation := &github.Installation{ + ID: github.Ptr(int64(67890)), + SuspendedAt: nil, + } + w.WriteHeader(http.StatusOK) + require.NoError(t, json.NewEncoder(w).Encode(installation)) + }), + ), + ), + appToken: "test-app-token", + installationID: "67890", + wantInstallation: conngh.AppInstallation{ + ID: 67890, + Enabled: true, + }, + wantErr: false, + }, + { + name: "invalid installation ID", + mockHandler: mockhub.NewMockedHTTPClient(), + appToken: "test-app-token", + installationID: "not-a-number", + wantInstallation: conngh.AppInstallation{}, + wantErr: true, + errContains: "invalid installation ID", + }, + { + name: "service unavailable", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetAppInstallationsByInstallationId, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusServiceUnavailable) + require.NoError(t, json.NewEncoder(w).Encode(github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusServiceUnavailable, + }, + Message: "Service unavailable", + })) + }), + ), + ), + appToken: "test-app-token", + installationID: "67890", + wantInstallation: conngh.AppInstallation{}, + wantErr: true, + }, + { + name: "installation not found", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetAppInstallationsByInstallationId, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusNotFound) + require.NoError(t, json.NewEncoder(w).Encode(github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusNotFound, + }, + Message: "Not Found", + })) + }), + ), + ), + appToken: "test-app-token", + installationID: "99999", + wantInstallation: conngh.AppInstallation{}, + wantErr: true, + }, + { + name: "other error", + mockHandler: mockhub.NewMockedHTTPClient( + mockhub.WithRequestMatchHandler( + mockhub.GetAppInstallationsByInstallationId, + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + require.NoError(t, json.NewEncoder(w).Encode(github.ErrorResponse{ + Response: &http.Response{ + StatusCode: http.StatusInternalServerError, + }, + Message: "Internal server error", + })) + }), + ), + ), + appToken: "test-app-token", + installationID: "67890", + wantInstallation: conngh.AppInstallation{}, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a mock client + ghClient := github.NewClient(tt.mockHandler) + client := conngh.NewClient(ghClient) + + // Call the method being tested + installation, err := client.GetAppInstallation(context.Background(), tt.installationID) + + // Check the error + if tt.wantErr { + assert.Error(t, err) + if tt.errContains != "" { + assert.Contains(t, err.Error(), tt.errContains) + } + } else { + assert.NoError(t, err) + } + + // Check the result + assert.Equal(t, tt.wantInstallation, installation) + }) + } +} diff --git a/apps/provisioning/pkg/connection/github/connection.go b/apps/provisioning/pkg/connection/github/connection.go new file mode 100644 index 00000000000..6a2da98ac8d --- /dev/null +++ b/apps/provisioning/pkg/connection/github/connection.go @@ -0,0 +1,192 @@ +package github + +import ( + "context" + "encoding/base64" + "errors" + "fmt" + "time" + + "github.com/golang-jwt/jwt/v4" + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + "github.com/grafana/grafana/apps/provisioning/pkg/connection" + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +//go:generate mockery --name GithubFactory --structname MockGithubFactory --inpackage --filename factory_mock.go --with-expecter +type GithubFactory interface { + New(ctx context.Context, ghToken common.RawSecureValue) Client +} + +type Connection struct { + obj *provisioning.Connection + ghFactory GithubFactory +} + +func NewConnection( + obj *provisioning.Connection, + factory GithubFactory, +) Connection { + return Connection{ + obj: obj, + ghFactory: factory, + } +} + +const ( + //TODO(ferruvich): these probably need to be setup in API configuration. + githubInstallationURL = "https://github.com/settings/installations" + jwtExpirationMinutes = 10 // GitHub Apps JWT tokens expire in 10 minutes maximum +) + +// Mutate performs in place mutation of the underneath resource. +func (c *Connection) Mutate(_ context.Context) error { + // Do nothing in case spec.Github is nil. + // If this field is required, we should fail at validation time. + if c.obj.Spec.GitHub == nil { + return nil + } + + c.obj.Spec.URL = fmt.Sprintf("%s/%s", githubInstallationURL, c.obj.Spec.GitHub.InstallationID) + + // Generate JWT token if private key is being provided. + // Same as for the spec.Github, if such a field is required, Validation will take care of that. + if !c.obj.Secure.PrivateKey.Create.IsZero() { + token, err := generateToken(c.obj.Spec.GitHub.AppID, c.obj.Secure.PrivateKey.Create) + if err != nil { + return fmt.Errorf("failed to generate JWT token: %w", err) + } + + // Store the generated token + c.obj.Secure.Token = common.InlineSecureValue{Create: token} + } + + return nil +} + +// Token generates and returns the Connection token. +func generateToken(appID string, privateKey common.RawSecureValue) (common.RawSecureValue, error) { + // Decode base64-encoded private key + privateKeyPEM, err := base64.StdEncoding.DecodeString(string(privateKey)) + if err != nil { + return "", fmt.Errorf("failed to decode base64 private key: %w", err) + } + + // Parse the private key + key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyPEM) + if err != nil { + return "", fmt.Errorf("failed to parse private key: %w", err) + } + + // Create the JWT token + now := time.Now() + claims := jwt.RegisteredClaims{ + IssuedAt: jwt.NewNumericDate(now), + ExpiresAt: jwt.NewNumericDate(now.Add(time.Duration(jwtExpirationMinutes) * time.Minute)), + Issuer: appID, + } + + token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) + signedToken, err := token.SignedString(key) + if err != nil { + return "", fmt.Errorf("failed to sign JWT token: %w", err) + } + + return common.RawSecureValue(signedToken), nil +} + +// Validate ensures the resource _looks_ correct. +func (c *Connection) Validate(ctx context.Context) error { + list := field.ErrorList{} + + if c.obj.Spec.Type != provisioning.GithubConnectionType { + list = append(list, field.Invalid(field.NewPath("spec", "type"), c.obj.Spec.Type, "invalid connection type")) + + // Doesn't make much sense to continue validating a connection which is not a Github one. + return toError(c.obj.GetName(), list) + } + + if c.obj.Spec.GitHub == nil { + list = append( + list, field.Required(field.NewPath("spec", "github"), "github info must be specified for GitHub connection"), + ) + + // Doesn't make much sense to continue validating a connection with no information. + return toError(c.obj.GetName(), list) + } + + if c.obj.Secure.PrivateKey.IsZero() { + list = append(list, field.Required(field.NewPath("secure", "privateKey"), "privateKey must be specified for GitHub connection")) + } + if c.obj.Secure.Token.IsZero() { + list = append(list, field.Required(field.NewPath("secure", "token"), "token must be specified for GitHub connection")) + } + if !c.obj.Secure.ClientSecret.IsZero() { + list = append(list, field.Forbidden(field.NewPath("secure", "clientSecret"), "clientSecret is forbidden in GitHub connection")) + } + + // Validate GitHub configuration fields + if c.obj.Spec.GitHub.AppID == "" { + list = append(list, field.Required(field.NewPath("spec", "github", "appID"), "appID must be specified for GitHub connection")) + } + if c.obj.Spec.GitHub.InstallationID == "" { + list = append(list, field.Required(field.NewPath("spec", "github", "installationID"), "installationID must be specified for GitHub connection")) + } + + // In case we have any error above, we don't go forward with the validation, and return the errors. + if len(list) > 0 { + return toError(c.obj.GetName(), list) + } + + // Validating app content via GH API + if err := c.validateAppAndInstallation(ctx); err != nil { + list = append(list, err) + } + + return toError(c.obj.GetName(), list) +} + +// validateAppAndInstallation validates the appID and installationID against the given github token. +func (c *Connection) validateAppAndInstallation(ctx context.Context) *field.Error { + ghClient := c.ghFactory.New(ctx, c.obj.Secure.Token.Create) + + app, err := ghClient.GetApp(ctx) + if err != nil { + if errors.Is(err, ErrServiceUnavailable) { + return field.InternalError(field.NewPath("spec", "token"), ErrServiceUnavailable) + } + return field.Invalid(field.NewPath("spec", "token"), "[REDACTED]", "invalid token") + } + + if fmt.Sprintf("%d", app.ID) != c.obj.Spec.GitHub.AppID { + return field.Invalid(field.NewPath("spec", "appID"), c.obj.Spec.GitHub.AppID, "appID mismatch") + } + + _, err = ghClient.GetAppInstallation(ctx, c.obj.Spec.GitHub.InstallationID) + if err != nil { + if errors.Is(err, ErrServiceUnavailable) { + return field.InternalError(field.NewPath("spec", "token"), ErrServiceUnavailable) + } + return field.Invalid(field.NewPath("spec", "installationID"), c.obj.Spec.GitHub.InstallationID, "invalid installation ID") + } + + return nil +} + +// toError converts a field.ErrorList to an error, returning nil if the list is empty +func toError(name string, list field.ErrorList) error { + if len(list) == 0 { + return nil + } + return apierrors.NewInvalid( + provisioning.ConnectionResourceInfo.GroupVersionKind().GroupKind(), + name, + list, + ) +} + +var ( + _ connection.Connection = (*Connection)(nil) +) diff --git a/apps/provisioning/pkg/connection/github/connection_test.go b/apps/provisioning/pkg/connection/github/connection_test.go new file mode 100644 index 00000000000..6a916db730e --- /dev/null +++ b/apps/provisioning/pkg/connection/github/connection_test.go @@ -0,0 +1,434 @@ +package github + +import ( + "context" + "encoding/base64" + "testing" + + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +//nolint:gosec // Test RSA private key (generated for testing purposes only) +const testPrivateKeyPEM = `-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAoInVbLY9io2Q/wHvUIXlEHg2Qyvd8eRzBAVEJ92DS6fx9H10 +06V0VRm78S0MXyo6i+n8ZAbZ0/R+GWpP2Ephxm0Gs2zo+iO2mpB19xQFI4o6ZTOw +b2WyjSaa2Vr4oyDkqti6AvfjW4VUAu932e08GkgwmmQSHXj7FX2CMWjgUwTTcuaX +65SHNKLNYLUP0HTumLzoZeqDTdoMMpKNdgH9Avr4/8vkVJ0mD6rqvxnw3JHsseNO +WdQTxf2aApBNHIIKxWZ2i/ZmjLNey7kltgjEquGiBdJvip3fHhH5XHdkrXcjRtnw +OJDnDmi5lQwv5yUBOSkbvbXRv/L/m0YLoD/fbwIDAQABAoIBAFfl//hM8/cnuesV ++R1Con/ZAgTXQOdPqPXbmEyniVrkMqMmCdBUOBTcST4s5yg36+RtkeaGpb/ajyyF +PAB2AYDucwvMpudGpJWOYTiOOp4R8hU1LvZfXVrRd1lo6NgQi4NLtNUpOtACeVQ+ +H4Yv0YemXQ47mnuOoRNMK/u3q5NoIdSahWptXBgUno8KklNpUrH3IYWaUxfBzDN3 +2xsVRTn2SfTSyoDmTDdTgptJONmoK1/sV7UsgWksdFc6XyYhsFAZgOGEJrBABRvF +546dyQ0cWxuPyVXpM7CN3tqC5ssvLjElg3LicK1V6gnjpdRnnvX88d1Eh3Uc/9IM +OZInT2ECgYEA6W8sQXTWinyEwl8SDKKMbB2ApIghAcFgdRxprZE4WFxjsYNCNL70 +dnSB7MRuzmxf5W77cV0N7JhH66N8HvY6Xq9olrpQ5dNttR4w8Pyv3wavDe8x7seL +5L2Xtbu7ihDr8Dk27MjiBSin3IxhBP5CJS910+pR6LrAWtEuU+FzFfECgYEAsA6y +qxHhCMXlTnauXhsnmPd1g61q7chW8kLQFYtHMLlQlgjHTW7irDZ9cPbPYDNjwRLO +7KLorcpv2NKe7rqq2ZyCm6hf1b9WnlQjo3dLpNWMu6fhy/smK8MgbRqcWpX+oTKF +79mK6hbY7o6eBzsQHBl7Z+LBNuwYmp9qOodPa18CgYEArv6ipKdcNhFGzRfMRiCN +OHederp6VACNuP2F05IsNUF9kxOdTEFirnKE++P+VU01TqA2azOhPp6iO+ohIGzi +MR06QNSH1OL9OWvasK4dggpWrRGF00VQgDgJRTnpS4WH+lxJ6pRlrAxgWpv6F24s +VAgSQr1Ejj2B+hMasdMvHWECgYBJ4uE4yhgXBnZlp4kmFV9Y4wF+cZkekaVrpn6N +jBYkbKFVVfnOlWqru3KJpgsB5I9IyAvvY68iwIKQDFSG+/AXw4dMrC0MF3DSoZ0T +TU2Br92QI7SvVod+djV1lGVp3ukt3XY4YqPZ+hywgUnw3uiz4j3YK2HLGup4ec6r +IX5DIQKBgHRLzvT3zqtlR1Oh0vv098clLwt+pGzXOxzJpxioOa5UqK13xIpFXbcg +iWUVh5YXCcuqaICUv4RLIEac5xQitk9Is/9IhP0NJ/81rHniosvdSpCeFXzxTImS +B8Uc0WUgheB4+yVKGnYpYaSOgFFI5+1BYUva/wDHLy2pWHz39Usb +-----END RSA PRIVATE KEY-----` + +func TestConnection_Mutate(t *testing.T) { + t.Run("should add URL to Github connection", func(t *testing.T) { + c := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Name: "test-private-key", + }, + }, + } + + mockFactory := NewMockGithubFactory(t) + conn := NewConnection(c, mockFactory) + + require.NoError(t, conn.Mutate(context.Background())) + assert.Equal(t, "https://github.com/settings/installations/456", c.Spec.URL) + }) + + t.Run("should generate JWT token when private key is provided", func(t *testing.T) { + privateKeyBase64 := base64.StdEncoding.EncodeToString([]byte(testPrivateKeyPEM)) + + c := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue(privateKeyBase64), + }, + }, + } + + mockFactory := NewMockGithubFactory(t) + conn := NewConnection(c, mockFactory) + + require.NoError(t, conn.Mutate(context.Background())) + assert.Equal(t, "https://github.com/settings/installations/456", c.Spec.URL) + assert.False(t, c.Secure.Token.Create.IsZero(), "JWT token should be generated") + }) + + t.Run("should do nothing when GitHub config is nil", func(t *testing.T) { + c := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GitlabConnectionType, + Gitlab: &provisioning.GitlabConnectionConfig{ + ClientID: "clientID", + }, + }, + } + + mockFactory := NewMockGithubFactory(t) + conn := NewConnection(c, mockFactory) + + require.NoError(t, conn.Mutate(context.Background())) + }) + + t.Run("should fail when private key is not base64", func(t *testing.T) { + c := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("invalid-key"), + }, + }, + } + + mockFactory := NewMockGithubFactory(t) + conn := NewConnection(c, mockFactory) + + err := conn.Mutate(context.Background()) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to generate JWT token") + assert.Contains(t, err.Error(), "failed to decode base64 private key") + }) + + t.Run("should fail when private key is invalid", func(t *testing.T) { + c := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue(base64.StdEncoding.EncodeToString([]byte("invalid-key"))), + }, + }, + } + + mockFactory := NewMockGithubFactory(t) + conn := NewConnection(c, mockFactory) + + err := conn.Mutate(context.Background()) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to generate JWT token") + assert.Contains(t, err.Error(), "failed to parse private key") + }) +} + +func TestConnection_Validate(t *testing.T) { + tests := []struct { + name string + connection *provisioning.Connection + setupMock func(*MockGithubFactory) + wantErr bool + errMsgContains []string + }{ + { + name: "invalid type returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: "invalid", + }, + }, + wantErr: true, + errMsgContains: []string{"spec.type"}, + }, + { + name: "github type without github config returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + }, + }, + wantErr: true, + errMsgContains: []string{"spec.github"}, + }, + { + name: "github type without private key returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + }, + wantErr: true, + errMsgContains: []string{"secure.privateKey"}, + }, + { + name: "github type without token returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("test-private-key"), + }, + }, + }, + wantErr: true, + errMsgContains: []string{"secure.token"}, + }, + { + name: "github type with client secret returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + ClientSecret: common.InlineSecureValue{ + Create: common.NewSecretValue("test-client-secret"), + }, + }, + }, + wantErr: true, + errMsgContains: []string{"secure.clientSecret"}, + }, + { + name: "github type without appID returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("test-private-key"), + }, + Token: common.InlineSecureValue{ + Create: common.NewSecretValue("test-token"), + }, + }, + }, + wantErr: true, + errMsgContains: []string{"spec.github.appID"}, + }, + { + name: "github type without installationID returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Name: "test-private-key", + }, + Token: common.InlineSecureValue{ + Name: "test-token", + }, + }, + }, + wantErr: true, + errMsgContains: []string{"spec.github.installationID"}, + }, + { + name: "github type with valid config is valid", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("test-private-key"), + }, + Token: common.InlineSecureValue{ + Create: common.NewSecretValue("test-token"), + }, + }, + }, + wantErr: false, + setupMock: func(mockFactory *MockGithubFactory) { + mockClient := NewMockClient(t) + + mockFactory.EXPECT().New(mock.Anything, common.RawSecureValue("test-token")).Return(mockClient) + mockClient.EXPECT().GetApp(mock.Anything).Return(App{ID: 123, Slug: "test-app"}, nil) + mockClient.EXPECT().GetAppInstallation(mock.Anything, "456").Return(AppInstallation{ID: 456}, nil) + }, + }, + { + name: "problem getting app returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("test-private-key"), + }, + Token: common.InlineSecureValue{ + Create: common.NewSecretValue("test-token"), + }, + }, + }, + wantErr: true, + errMsgContains: []string{"spec.token", "[REDACTED]"}, + setupMock: func(mockFactory *MockGithubFactory) { + mockClient := NewMockClient(t) + + mockFactory.EXPECT().New(mock.Anything, common.RawSecureValue("test-token")).Return(mockClient) + mockClient.EXPECT().GetApp(mock.Anything).Return(App{}, assert.AnError) + }, + }, + { + name: "mismatched app ID returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("test-private-key"), + }, + Token: common.InlineSecureValue{ + Create: common.NewSecretValue("test-token"), + }, + }, + }, + wantErr: true, + errMsgContains: []string{"spec.appID"}, + setupMock: func(mockFactory *MockGithubFactory) { + mockClient := NewMockClient(t) + + mockFactory.EXPECT().New(mock.Anything, common.RawSecureValue("test-token")).Return(mockClient) + mockClient.EXPECT().GetApp(mock.Anything).Return(App{ID: 444, Slug: "test-app"}, nil) + }, + }, + { + name: "problem when getting installation returns error", + connection: &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("test-private-key"), + }, + Token: common.InlineSecureValue{ + Create: common.NewSecretValue("test-token"), + }, + }, + }, + wantErr: true, + errMsgContains: []string{"spec.installationID", "456"}, + setupMock: func(mockFactory *MockGithubFactory) { + mockClient := NewMockClient(t) + + mockFactory.EXPECT().New(mock.Anything, common.RawSecureValue("test-token")).Return(mockClient) + mockClient.EXPECT().GetApp(mock.Anything).Return(App{ID: 123, Slug: "test-app"}, nil) + mockClient.EXPECT().GetAppInstallation(mock.Anything, "456").Return(AppInstallation{}, assert.AnError) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockFactory := NewMockGithubFactory(t) + if tt.setupMock != nil { + tt.setupMock(mockFactory) + } + + conn := NewConnection(tt.connection, mockFactory) + err := conn.Validate(context.Background()) + if tt.wantErr { + assert.Error(t, err) + for _, msg := range tt.errMsgContains { + assert.Contains(t, err.Error(), msg) + } + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/apps/provisioning/pkg/connection/github/extra.go b/apps/provisioning/pkg/connection/github/extra.go new file mode 100644 index 00000000000..2c207637c61 --- /dev/null +++ b/apps/provisioning/pkg/connection/github/extra.go @@ -0,0 +1,36 @@ +package github + +import ( + "context" + "fmt" + + "github.com/grafana/grafana-app-sdk/logging" + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + "github.com/grafana/grafana/apps/provisioning/pkg/connection" +) + +type extra struct { + factory GithubFactory +} + +func (e *extra) Type() provisioning.ConnectionType { + return provisioning.GithubConnectionType +} + +func (e *extra) Build(ctx context.Context, connection *provisioning.Connection) (connection.Connection, error) { + logger := logging.FromContext(ctx) + if connection == nil || connection.Spec.GitHub == nil { + logger.Error("connection is nil or github info is nil") + + return nil, fmt.Errorf("invalid github connection") + } + + c := NewConnection(connection, e.factory) + return &c, nil +} + +func Extra(factory GithubFactory) connection.Extra { + return &extra{ + factory: factory, + } +} diff --git a/apps/provisioning/pkg/connection/github/extra_test.go b/apps/provisioning/pkg/connection/github/extra_test.go new file mode 100644 index 00000000000..c5bcc8279d9 --- /dev/null +++ b/apps/provisioning/pkg/connection/github/extra_test.go @@ -0,0 +1,126 @@ +package github_test + +import ( + "context" + "testing" + + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + "github.com/grafana/grafana/apps/provisioning/pkg/connection/github" + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestExtra_Type(t *testing.T) { + t.Run("should return GithubConnectionType", func(t *testing.T) { + mockFactory := github.NewMockGithubFactory(t) + e := github.Extra(mockFactory) + result := e.Type() + assert.Equal(t, provisioning.GithubConnectionType, result) + }) +} + +func TestExtra_Build(t *testing.T) { + t.Run("should successfully build connection", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Create: common.NewSecretValue("test-private-key"), + }, + }, + } + + mockFactory := github.NewMockGithubFactory(t) + + e := github.Extra(mockFactory) + + result, err := e.Build(ctx, conn) + require.NoError(t, err) + require.NotNil(t, result) + }) + + t.Run("should handle different connection configurations", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "another-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "789", + InstallationID: "101112", + }, + }, + Secure: provisioning.ConnectionSecure{ + PrivateKey: common.InlineSecureValue{ + Name: "existing-private-key", + }, + Token: common.InlineSecureValue{ + Name: "existing-token", + }, + }, + } + + mockFactory := github.NewMockGithubFactory(t) + + e := github.Extra(mockFactory) + + result, err := e.Build(ctx, conn) + require.NoError(t, err) + require.NotNil(t, result) + }) + + t.Run("should build connection with background context", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + } + + mockFactory := github.NewMockGithubFactory(t) + e := github.Extra(mockFactory) + result, err := e.Build(ctx, conn) + require.NoError(t, err) + require.NotNil(t, result) + }) + + t.Run("should always pass empty token to factory.New", func(t *testing.T) { + ctx := context.Background() + conn := &provisioning.Connection{ + ObjectMeta: metav1.ObjectMeta{Name: "test-connection"}, + Spec: provisioning.ConnectionSpec{ + Type: provisioning.GithubConnectionType, + GitHub: &provisioning.GitHubConnectionConfig{ + AppID: "123", + InstallationID: "456", + }, + }, + Secure: provisioning.ConnectionSecure{ + Token: common.InlineSecureValue{ + Create: common.NewSecretValue("some-token"), + }, + }, + } + + mockFactory := github.NewMockGithubFactory(t) + e := github.Extra(mockFactory) + result, err := e.Build(ctx, conn) + require.NoError(t, err) + require.NotNil(t, result) + }) +} diff --git a/apps/provisioning/pkg/connection/github/factory.go b/apps/provisioning/pkg/connection/github/factory.go new file mode 100644 index 00000000000..2399f3c9f69 --- /dev/null +++ b/apps/provisioning/pkg/connection/github/factory.go @@ -0,0 +1,39 @@ +package github + +import ( + "context" + "net/http" + + "github.com/google/go-github/v70/github" + "golang.org/x/oauth2" + + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +// Factory creates new GitHub clients. +// It exists only for the ability to test the code easily. +type Factory struct { + // Client allows overriding the client to use in the GH client returned. It exists primarily for testing. + // FIXME: we should replace in this way. We should add some options pattern for the factory. + Client *http.Client +} + +func ProvideFactory() GithubFactory { + return &Factory{} +} + +func (r *Factory) New(ctx context.Context, ghToken common.RawSecureValue) Client { + if r.Client != nil { + return NewClient(github.NewClient(r.Client)) + } + + if !ghToken.IsZero() { + tokenSrc := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: string(ghToken)}, + ) + tokenClient := oauth2.NewClient(ctx, tokenSrc) + return NewClient(github.NewClient(tokenClient)) + } + + return NewClient(github.NewClient(&http.Client{})) +} diff --git a/apps/provisioning/pkg/connection/github/factory_mock.go b/apps/provisioning/pkg/connection/github/factory_mock.go new file mode 100644 index 00000000000..a9e1424b62d --- /dev/null +++ b/apps/provisioning/pkg/connection/github/factory_mock.go @@ -0,0 +1,86 @@ +// Code generated by mockery v2.53.4. DO NOT EDIT. + +package github + +import ( + context "context" + + v0alpha1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + mock "github.com/stretchr/testify/mock" +) + +// MockGithubFactory is an autogenerated mock type for the GithubFactory type +type MockGithubFactory struct { + mock.Mock +} + +type MockGithubFactory_Expecter struct { + mock *mock.Mock +} + +func (_m *MockGithubFactory) EXPECT() *MockGithubFactory_Expecter { + return &MockGithubFactory_Expecter{mock: &_m.Mock} +} + +// New provides a mock function with given fields: ctx, ghToken +func (_m *MockGithubFactory) New(ctx context.Context, ghToken v0alpha1.RawSecureValue) Client { + ret := _m.Called(ctx, ghToken) + + if len(ret) == 0 { + panic("no return value specified for New") + } + + var r0 Client + if rf, ok := ret.Get(0).(func(context.Context, v0alpha1.RawSecureValue) Client); ok { + r0 = rf(ctx, ghToken) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(Client) + } + } + + return r0 +} + +// MockGithubFactory_New_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'New' +type MockGithubFactory_New_Call struct { + *mock.Call +} + +// New is a helper method to define mock.On call +// - ctx context.Context +// - ghToken v0alpha1.RawSecureValue +func (_e *MockGithubFactory_Expecter) New(ctx interface{}, ghToken interface{}) *MockGithubFactory_New_Call { + return &MockGithubFactory_New_Call{Call: _e.mock.On("New", ctx, ghToken)} +} + +func (_c *MockGithubFactory_New_Call) Run(run func(ctx context.Context, ghToken v0alpha1.RawSecureValue)) *MockGithubFactory_New_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(v0alpha1.RawSecureValue)) + }) + return _c +} + +func (_c *MockGithubFactory_New_Call) Return(_a0 Client) *MockGithubFactory_New_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *MockGithubFactory_New_Call) RunAndReturn(run func(context.Context, v0alpha1.RawSecureValue) Client) *MockGithubFactory_New_Call { + _c.Call.Return(run) + return _c +} + +// NewMockGithubFactory creates a new instance of MockGithubFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockGithubFactory(t interface { + mock.TestingT + Cleanup(func()) +}) *MockGithubFactory { + mock := &MockGithubFactory{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/apps/provisioning/pkg/controller/connection_status.go b/apps/provisioning/pkg/controller/connection_status.go new file mode 100644 index 00000000000..0d8a0002f41 --- /dev/null +++ b/apps/provisioning/pkg/controller/connection_status.go @@ -0,0 +1,40 @@ +package controller + +import ( + "context" + "encoding/json" + "fmt" + + provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + client "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" +) + +// ConnectionStatusPatcher provides methods to patch Connection status subresources. +type ConnectionStatusPatcher struct { + client client.ProvisioningV0alpha1Interface +} + +// NewConnectionStatusPatcher creates a new ConnectionStatusPatcher. +func NewConnectionStatusPatcher(client client.ProvisioningV0alpha1Interface) *ConnectionStatusPatcher { + return &ConnectionStatusPatcher{ + client: client, + } +} + +// Patch applies JSON patch operations to a Connection's status subresource. +func (p *ConnectionStatusPatcher) Patch(ctx context.Context, conn *provisioning.Connection, patchOperations ...map[string]interface{}) error { + patch, err := json.Marshal(patchOperations) + if err != nil { + return fmt.Errorf("unable to marshal patch data: %w", err) + } + + _, err = p.client.Connections(conn.Namespace). + Patch(ctx, conn.Name, types.JSONPatchType, patch, metav1.PatchOptions{}, "status") + if err != nil { + return fmt.Errorf("unable to update connection status: %w", err) + } + + return nil +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/bitbucketconnectionconfig.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/bitbucketconnectionconfig.go new file mode 100644 index 00000000000..9a3604afe71 --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/bitbucketconnectionconfig.go @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +// BitbucketConnectionConfigApplyConfiguration represents a declarative configuration of the BitbucketConnectionConfig type for use +// with apply. +type BitbucketConnectionConfigApplyConfiguration struct { + ClientID *string `json:"clientID,omitempty"` +} + +// BitbucketConnectionConfigApplyConfiguration constructs a declarative configuration of the BitbucketConnectionConfig type for use with +// apply. +func BitbucketConnectionConfig() *BitbucketConnectionConfigApplyConfiguration { + return &BitbucketConnectionConfigApplyConfiguration{} +} + +// WithClientID sets the ClientID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ClientID field is set to the value of the last call. +func (b *BitbucketConnectionConfigApplyConfiguration) WithClientID(value string) *BitbucketConnectionConfigApplyConfiguration { + b.ClientID = &value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connection.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connection.go new file mode 100644 index 00000000000..a7a56c62a14 --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connection.go @@ -0,0 +1,237 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// ConnectionApplyConfiguration represents a declarative configuration of the Connection type for use +// with apply. +type ConnectionApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *ConnectionSpecApplyConfiguration `json:"spec,omitempty"` + Secure *ConnectionSecureApplyConfiguration `json:"secure,omitempty"` + Status *ConnectionStatusApplyConfiguration `json:"status,omitempty"` +} + +// Connection constructs a declarative configuration of the Connection type for use with +// apply. +func Connection(name, namespace string) *ConnectionApplyConfiguration { + b := &ConnectionApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("Connection") + b.WithAPIVersion("provisioning.grafana.app/v0alpha1") + return b +} +func (b ConnectionApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithKind(value string) *ConnectionApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithAPIVersion(value string) *ConnectionApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithName(value string) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithGenerateName(value string) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithNamespace(value string) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithUID(value types.UID) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithResourceVersion(value string) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithGeneration(value int64) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *ConnectionApplyConfiguration) WithLabels(entries map[string]string) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *ConnectionApplyConfiguration) WithAnnotations(entries map[string]string) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *ConnectionApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *ConnectionApplyConfiguration) WithFinalizers(values ...string) *ConnectionApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *ConnectionApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithSpec(value *ConnectionSpecApplyConfiguration) *ConnectionApplyConfiguration { + b.Spec = value + return b +} + +// WithSecure sets the Secure field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Secure field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithSecure(value *ConnectionSecureApplyConfiguration) *ConnectionApplyConfiguration { + b.Secure = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *ConnectionApplyConfiguration) WithStatus(value *ConnectionStatusApplyConfiguration) *ConnectionApplyConfiguration { + b.Status = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *ConnectionApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *ConnectionApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *ConnectionApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *ConnectionApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectioninfo.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectioninfo.go new file mode 100644 index 00000000000..87e4aa7e180 --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectioninfo.go @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +// ConnectionInfoApplyConfiguration represents a declarative configuration of the ConnectionInfo type for use +// with apply. +type ConnectionInfoApplyConfiguration struct { + Name *string `json:"name,omitempty"` +} + +// ConnectionInfoApplyConfiguration constructs a declarative configuration of the ConnectionInfo type for use with +// apply. +func ConnectionInfo() *ConnectionInfoApplyConfiguration { + return &ConnectionInfoApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *ConnectionInfoApplyConfiguration) WithName(value string) *ConnectionInfoApplyConfiguration { + b.Name = &value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionsecure.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionsecure.go new file mode 100644 index 00000000000..f5be635560d --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionsecure.go @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + commonv0alpha1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +// ConnectionSecureApplyConfiguration represents a declarative configuration of the ConnectionSecure type for use +// with apply. +type ConnectionSecureApplyConfiguration struct { + PrivateKey *commonv0alpha1.InlineSecureValue `json:"privateKey,omitempty"` + ClientSecret *commonv0alpha1.InlineSecureValue `json:"clientSecret,omitempty"` + Token *commonv0alpha1.InlineSecureValue `json:"token,omitempty"` +} + +// ConnectionSecureApplyConfiguration constructs a declarative configuration of the ConnectionSecure type for use with +// apply. +func ConnectionSecure() *ConnectionSecureApplyConfiguration { + return &ConnectionSecureApplyConfiguration{} +} + +// WithPrivateKey sets the PrivateKey field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the PrivateKey field is set to the value of the last call. +func (b *ConnectionSecureApplyConfiguration) WithPrivateKey(value commonv0alpha1.InlineSecureValue) *ConnectionSecureApplyConfiguration { + b.PrivateKey = &value + return b +} + +// WithClientSecret sets the ClientSecret field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ClientSecret field is set to the value of the last call. +func (b *ConnectionSecureApplyConfiguration) WithClientSecret(value commonv0alpha1.InlineSecureValue) *ConnectionSecureApplyConfiguration { + b.ClientSecret = &value + return b +} + +// WithToken sets the Token field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Token field is set to the value of the last call. +func (b *ConnectionSecureApplyConfiguration) WithToken(value commonv0alpha1.InlineSecureValue) *ConnectionSecureApplyConfiguration { + b.Token = &value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionspec.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionspec.go new file mode 100644 index 00000000000..1b55b832ae1 --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionspec.go @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + provisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" +) + +// ConnectionSpecApplyConfiguration represents a declarative configuration of the ConnectionSpec type for use +// with apply. +type ConnectionSpecApplyConfiguration struct { + Type *provisioningv0alpha1.ConnectionType `json:"type,omitempty"` + URL *string `json:"url,omitempty"` + GitHub *GitHubConnectionConfigApplyConfiguration `json:"github,omitempty"` + Bitbucket *BitbucketConnectionConfigApplyConfiguration `json:"bitbucket,omitempty"` + Gitlab *GitlabConnectionConfigApplyConfiguration `json:"gitlab,omitempty"` +} + +// ConnectionSpecApplyConfiguration constructs a declarative configuration of the ConnectionSpec type for use with +// apply. +func ConnectionSpec() *ConnectionSpecApplyConfiguration { + return &ConnectionSpecApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *ConnectionSpecApplyConfiguration) WithType(value provisioningv0alpha1.ConnectionType) *ConnectionSpecApplyConfiguration { + b.Type = &value + return b +} + +// WithURL sets the URL field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the URL field is set to the value of the last call. +func (b *ConnectionSpecApplyConfiguration) WithURL(value string) *ConnectionSpecApplyConfiguration { + b.URL = &value + return b +} + +// WithGitHub sets the GitHub field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GitHub field is set to the value of the last call. +func (b *ConnectionSpecApplyConfiguration) WithGitHub(value *GitHubConnectionConfigApplyConfiguration) *ConnectionSpecApplyConfiguration { + b.GitHub = value + return b +} + +// WithBitbucket sets the Bitbucket field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Bitbucket field is set to the value of the last call. +func (b *ConnectionSpecApplyConfiguration) WithBitbucket(value *BitbucketConnectionConfigApplyConfiguration) *ConnectionSpecApplyConfiguration { + b.Bitbucket = value + return b +} + +// WithGitlab sets the Gitlab field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Gitlab field is set to the value of the last call. +func (b *ConnectionSpecApplyConfiguration) WithGitlab(value *GitlabConnectionConfigApplyConfiguration) *ConnectionSpecApplyConfiguration { + b.Gitlab = value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionstatus.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionstatus.go new file mode 100644 index 00000000000..b9d510aac91 --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/connectionstatus.go @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + provisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" +) + +// ConnectionStatusApplyConfiguration represents a declarative configuration of the ConnectionStatus type for use +// with apply. +type ConnectionStatusApplyConfiguration struct { + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + State *provisioningv0alpha1.ConnectionState `json:"state,omitempty"` + Health *HealthStatusApplyConfiguration `json:"health,omitempty"` +} + +// ConnectionStatusApplyConfiguration constructs a declarative configuration of the ConnectionStatus type for use with +// apply. +func ConnectionStatus() *ConnectionStatusApplyConfiguration { + return &ConnectionStatusApplyConfiguration{} +} + +// WithObservedGeneration sets the ObservedGeneration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ObservedGeneration field is set to the value of the last call. +func (b *ConnectionStatusApplyConfiguration) WithObservedGeneration(value int64) *ConnectionStatusApplyConfiguration { + b.ObservedGeneration = &value + return b +} + +// WithState sets the State field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the State field is set to the value of the last call. +func (b *ConnectionStatusApplyConfiguration) WithState(value provisioningv0alpha1.ConnectionState) *ConnectionStatusApplyConfiguration { + b.State = &value + return b +} + +// WithHealth sets the Health field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Health field is set to the value of the last call. +func (b *ConnectionStatusApplyConfiguration) WithHealth(value *HealthStatusApplyConfiguration) *ConnectionStatusApplyConfiguration { + b.Health = value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/githubconnectionconfig.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/githubconnectionconfig.go new file mode 100644 index 00000000000..c2f2a8b291b --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/githubconnectionconfig.go @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +// GitHubConnectionConfigApplyConfiguration represents a declarative configuration of the GitHubConnectionConfig type for use +// with apply. +type GitHubConnectionConfigApplyConfiguration struct { + AppID *string `json:"appID,omitempty"` + InstallationID *string `json:"installationID,omitempty"` +} + +// GitHubConnectionConfigApplyConfiguration constructs a declarative configuration of the GitHubConnectionConfig type for use with +// apply. +func GitHubConnectionConfig() *GitHubConnectionConfigApplyConfiguration { + return &GitHubConnectionConfigApplyConfiguration{} +} + +// WithAppID sets the AppID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AppID field is set to the value of the last call. +func (b *GitHubConnectionConfigApplyConfiguration) WithAppID(value string) *GitHubConnectionConfigApplyConfiguration { + b.AppID = &value + return b +} + +// WithInstallationID sets the InstallationID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the InstallationID field is set to the value of the last call. +func (b *GitHubConnectionConfigApplyConfiguration) WithInstallationID(value string) *GitHubConnectionConfigApplyConfiguration { + b.InstallationID = &value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/gitlabconnectionconfig.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/gitlabconnectionconfig.go new file mode 100644 index 00000000000..0238ae3c226 --- /dev/null +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/gitlabconnectionconfig.go @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v0alpha1 + +// GitlabConnectionConfigApplyConfiguration represents a declarative configuration of the GitlabConnectionConfig type for use +// with apply. +type GitlabConnectionConfigApplyConfiguration struct { + ClientID *string `json:"clientID,omitempty"` +} + +// GitlabConnectionConfigApplyConfiguration constructs a declarative configuration of the GitlabConnectionConfig type for use with +// apply. +func GitlabConnectionConfig() *GitlabConnectionConfigApplyConfiguration { + return &GitlabConnectionConfigApplyConfiguration{} +} + +// WithClientID sets the ClientID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ClientID field is set to the value of the last call. +func (b *GitlabConnectionConfigApplyConfiguration) WithClientID(value string) *GitlabConnectionConfigApplyConfiguration { + b.ClientID = &value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobresourcesummary.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobresourcesummary.go index ed6a62f651a..8986d2f85a6 100644 --- a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobresourcesummary.go +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobresourcesummary.go @@ -7,16 +7,18 @@ package v0alpha1 // JobResourceSummaryApplyConfiguration represents a declarative configuration of the JobResourceSummary type for use // with apply. type JobResourceSummaryApplyConfiguration struct { - Group *string `json:"group,omitempty"` - Kind *string `json:"kind,omitempty"` - Total *int64 `json:"total,omitempty"` - Create *int64 `json:"create,omitempty"` - Update *int64 `json:"update,omitempty"` - Delete *int64 `json:"delete,omitempty"` - Write *int64 `json:"write,omitempty"` - Error *int64 `json:"error,omitempty"` - Noop *int64 `json:"noop,omitempty"` - Errors []string `json:"errors,omitempty"` + Group *string `json:"group,omitempty"` + Kind *string `json:"kind,omitempty"` + Total *int64 `json:"total,omitempty"` + Create *int64 `json:"create,omitempty"` + Update *int64 `json:"update,omitempty"` + Delete *int64 `json:"delete,omitempty"` + Write *int64 `json:"write,omitempty"` + Error *int64 `json:"error,omitempty"` + Warning *int64 `json:"warning,omitempty"` + Noop *int64 `json:"noop,omitempty"` + Errors []string `json:"errors,omitempty"` + Warnings []string `json:"warnings,omitempty"` } // JobResourceSummaryApplyConfiguration constructs a declarative configuration of the JobResourceSummary type for use with @@ -89,6 +91,14 @@ func (b *JobResourceSummaryApplyConfiguration) WithError(value int64) *JobResour return b } +// WithWarning sets the Warning field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Warning field is set to the value of the last call. +func (b *JobResourceSummaryApplyConfiguration) WithWarning(value int64) *JobResourceSummaryApplyConfiguration { + b.Warning = &value + return b +} + // WithNoop sets the Noop field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Noop field is set to the value of the last call. @@ -106,3 +116,13 @@ func (b *JobResourceSummaryApplyConfiguration) WithErrors(values ...string) *Job } return b } + +// WithWarnings adds the given value to the Warnings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Warnings field. +func (b *JobResourceSummaryApplyConfiguration) WithWarnings(values ...string) *JobResourceSummaryApplyConfiguration { + for i := range values { + b.Warnings = append(b.Warnings, values[i]) + } + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobstatus.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobstatus.go index ea9228473a5..0ad62090c62 100644 --- a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobstatus.go +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/jobstatus.go @@ -16,6 +16,7 @@ type JobStatusApplyConfiguration struct { Finished *int64 `json:"finished,omitempty"` Message *string `json:"message,omitempty"` Errors []string `json:"errors,omitempty"` + Warnings []string `json:"warnings,omitempty"` Progress *float64 `json:"progress,omitempty"` Summary []*provisioningv0alpha1.JobResourceSummary `json:"summary,omitempty"` URLs *RepositoryURLsApplyConfiguration `json:"url,omitempty"` @@ -69,6 +70,16 @@ func (b *JobStatusApplyConfiguration) WithErrors(values ...string) *JobStatusApp return b } +// WithWarnings adds the given value to the Warnings field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Warnings field. +func (b *JobStatusApplyConfiguration) WithWarnings(values ...string) *JobStatusApplyConfiguration { + for i := range values { + b.Warnings = append(b.Warnings, values[i]) + } + return b +} + // WithProgress sets the Progress field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Progress field is set to the value of the last call. diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/migratejoboptions.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/migratejoboptions.go index aee0b05fa3a..7f689c19585 100644 --- a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/migratejoboptions.go +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/migratejoboptions.go @@ -7,7 +7,6 @@ package v0alpha1 // MigrateJobOptionsApplyConfiguration represents a declarative configuration of the MigrateJobOptions type for use // with apply. type MigrateJobOptionsApplyConfiguration struct { - History *bool `json:"history,omitempty"` Message *string `json:"message,omitempty"` } @@ -17,14 +16,6 @@ func MigrateJobOptions() *MigrateJobOptionsApplyConfiguration { return &MigrateJobOptionsApplyConfiguration{} } -// WithHistory sets the History field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the History field is set to the value of the last call. -func (b *MigrateJobOptionsApplyConfiguration) WithHistory(value bool) *MigrateJobOptionsApplyConfiguration { - b.History = &value - return b -} - // WithMessage sets the Message field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Message field is set to the value of the last call. diff --git a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/repositoryspec.go b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/repositoryspec.go index 6fff6f2de42..5caf805702b 100644 --- a/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/repositoryspec.go +++ b/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1/repositoryspec.go @@ -21,6 +21,7 @@ type RepositorySpecApplyConfiguration struct { Git *GitRepositoryConfigApplyConfiguration `json:"git,omitempty"` Bitbucket *BitbucketRepositoryConfigApplyConfiguration `json:"bitbucket,omitempty"` GitLab *GitLabRepositoryConfigApplyConfiguration `json:"gitlab,omitempty"` + Connection *ConnectionInfoApplyConfiguration `json:"connection,omitempty"` } // RepositorySpecApplyConfiguration constructs a declarative configuration of the RepositorySpec type for use with @@ -110,3 +111,11 @@ func (b *RepositorySpecApplyConfiguration) WithGitLab(value *GitLabRepositoryCon b.GitLab = value return b } + +// WithConnection sets the Connection field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Connection field is set to the value of the last call. +func (b *RepositorySpecApplyConfiguration) WithConnection(value *ConnectionInfoApplyConfiguration) *RepositorySpecApplyConfiguration { + b.Connection = value + return b +} diff --git a/apps/provisioning/pkg/generated/applyconfiguration/utils.go b/apps/provisioning/pkg/generated/applyconfiguration/utils.go index 400f2b7c083..7168418b82d 100644 --- a/apps/provisioning/pkg/generated/applyconfiguration/utils.go +++ b/apps/provisioning/pkg/generated/applyconfiguration/utils.go @@ -18,14 +18,30 @@ import ( func ForKind(kind schema.GroupVersionKind) interface{} { switch kind { // Group=provisioning.grafana.app, Version=v0alpha1 + case v0alpha1.SchemeGroupVersion.WithKind("BitbucketConnectionConfig"): + return &provisioningv0alpha1.BitbucketConnectionConfigApplyConfiguration{} case v0alpha1.SchemeGroupVersion.WithKind("BitbucketRepositoryConfig"): return &provisioningv0alpha1.BitbucketRepositoryConfigApplyConfiguration{} + case v0alpha1.SchemeGroupVersion.WithKind("Connection"): + return &provisioningv0alpha1.ConnectionApplyConfiguration{} + case v0alpha1.SchemeGroupVersion.WithKind("ConnectionInfo"): + return &provisioningv0alpha1.ConnectionInfoApplyConfiguration{} + case v0alpha1.SchemeGroupVersion.WithKind("ConnectionSecure"): + return &provisioningv0alpha1.ConnectionSecureApplyConfiguration{} + case v0alpha1.SchemeGroupVersion.WithKind("ConnectionSpec"): + return &provisioningv0alpha1.ConnectionSpecApplyConfiguration{} + case v0alpha1.SchemeGroupVersion.WithKind("ConnectionStatus"): + return &provisioningv0alpha1.ConnectionStatusApplyConfiguration{} case v0alpha1.SchemeGroupVersion.WithKind("DeleteJobOptions"): return &provisioningv0alpha1.DeleteJobOptionsApplyConfiguration{} case v0alpha1.SchemeGroupVersion.WithKind("ExportJobOptions"): return &provisioningv0alpha1.ExportJobOptionsApplyConfiguration{} + case v0alpha1.SchemeGroupVersion.WithKind("GitHubConnectionConfig"): + return &provisioningv0alpha1.GitHubConnectionConfigApplyConfiguration{} case v0alpha1.SchemeGroupVersion.WithKind("GitHubRepositoryConfig"): return &provisioningv0alpha1.GitHubRepositoryConfigApplyConfiguration{} + case v0alpha1.SchemeGroupVersion.WithKind("GitlabConnectionConfig"): + return &provisioningv0alpha1.GitlabConnectionConfigApplyConfiguration{} case v0alpha1.SchemeGroupVersion.WithKind("GitLabRepositoryConfig"): return &provisioningv0alpha1.GitLabRepositoryConfigApplyConfiguration{} case v0alpha1.SchemeGroupVersion.WithKind("GitRepositoryConfig"): diff --git a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/connection.go b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/connection.go new file mode 100644 index 00000000000..fe585e5c0bb --- /dev/null +++ b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/connection.go @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by client-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + context "context" + + provisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + applyconfigurationprovisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1" + scheme "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// ConnectionsGetter has a method to return a ConnectionInterface. +// A group's client should implement this interface. +type ConnectionsGetter interface { + Connections(namespace string) ConnectionInterface +} + +// ConnectionInterface has methods to work with Connection resources. +type ConnectionInterface interface { + Create(ctx context.Context, connection *provisioningv0alpha1.Connection, opts v1.CreateOptions) (*provisioningv0alpha1.Connection, error) + Update(ctx context.Context, connection *provisioningv0alpha1.Connection, opts v1.UpdateOptions) (*provisioningv0alpha1.Connection, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, connection *provisioningv0alpha1.Connection, opts v1.UpdateOptions) (*provisioningv0alpha1.Connection, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*provisioningv0alpha1.Connection, error) + List(ctx context.Context, opts v1.ListOptions) (*provisioningv0alpha1.ConnectionList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *provisioningv0alpha1.Connection, err error) + Apply(ctx context.Context, connection *applyconfigurationprovisioningv0alpha1.ConnectionApplyConfiguration, opts v1.ApplyOptions) (result *provisioningv0alpha1.Connection, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, connection *applyconfigurationprovisioningv0alpha1.ConnectionApplyConfiguration, opts v1.ApplyOptions) (result *provisioningv0alpha1.Connection, err error) + ConnectionExpansion +} + +// connections implements ConnectionInterface +type connections struct { + *gentype.ClientWithListAndApply[*provisioningv0alpha1.Connection, *provisioningv0alpha1.ConnectionList, *applyconfigurationprovisioningv0alpha1.ConnectionApplyConfiguration] +} + +// newConnections returns a Connections +func newConnections(c *ProvisioningV0alpha1Client, namespace string) *connections { + return &connections{ + gentype.NewClientWithListAndApply[*provisioningv0alpha1.Connection, *provisioningv0alpha1.ConnectionList, *applyconfigurationprovisioningv0alpha1.ConnectionApplyConfiguration]( + "connections", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *provisioningv0alpha1.Connection { return &provisioningv0alpha1.Connection{} }, + func() *provisioningv0alpha1.ConnectionList { return &provisioningv0alpha1.ConnectionList{} }, + ), + } +} diff --git a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/fake/fake_connection.go b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/fake/fake_connection.go new file mode 100644 index 00000000000..2059d044172 --- /dev/null +++ b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/fake/fake_connection.go @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + provisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/generated/applyconfiguration/provisioning/v0alpha1" + typedprovisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1" + gentype "k8s.io/client-go/gentype" +) + +// fakeConnections implements ConnectionInterface +type fakeConnections struct { + *gentype.FakeClientWithListAndApply[*v0alpha1.Connection, *v0alpha1.ConnectionList, *provisioningv0alpha1.ConnectionApplyConfiguration] + Fake *FakeProvisioningV0alpha1 +} + +func newFakeConnections(fake *FakeProvisioningV0alpha1, namespace string) typedprovisioningv0alpha1.ConnectionInterface { + return &fakeConnections{ + gentype.NewFakeClientWithListAndApply[*v0alpha1.Connection, *v0alpha1.ConnectionList, *provisioningv0alpha1.ConnectionApplyConfiguration]( + fake.Fake, + namespace, + v0alpha1.SchemeGroupVersion.WithResource("connections"), + v0alpha1.SchemeGroupVersion.WithKind("Connection"), + func() *v0alpha1.Connection { return &v0alpha1.Connection{} }, + func() *v0alpha1.ConnectionList { return &v0alpha1.ConnectionList{} }, + func(dst, src *v0alpha1.ConnectionList) { dst.ListMeta = src.ListMeta }, + func(list *v0alpha1.ConnectionList) []*v0alpha1.Connection { return gentype.ToPointerSlice(list.Items) }, + func(list *v0alpha1.ConnectionList, items []*v0alpha1.Connection) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/fake/fake_provisioning_client.go b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/fake/fake_provisioning_client.go index d6fe94156be..2f1422cadc1 100644 --- a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/fake/fake_provisioning_client.go +++ b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/fake/fake_provisioning_client.go @@ -14,6 +14,10 @@ type FakeProvisioningV0alpha1 struct { *testing.Fake } +func (c *FakeProvisioningV0alpha1) Connections(namespace string) v0alpha1.ConnectionInterface { + return newFakeConnections(c, namespace) +} + func (c *FakeProvisioningV0alpha1) HistoricJobs(namespace string) v0alpha1.HistoricJobInterface { return newFakeHistoricJobs(c, namespace) } diff --git a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/generated_expansion.go b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/generated_expansion.go index 21b7a18b414..5220accc813 100644 --- a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/generated_expansion.go +++ b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/generated_expansion.go @@ -4,6 +4,8 @@ package v0alpha1 +type ConnectionExpansion interface{} + type HistoricJobExpansion interface{} type JobExpansion interface{} diff --git a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/provisioning_client.go b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/provisioning_client.go index 401bc533cfe..03a1e2e0ceb 100644 --- a/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/provisioning_client.go +++ b/apps/provisioning/pkg/generated/clientset/versioned/typed/provisioning/v0alpha1/provisioning_client.go @@ -14,6 +14,7 @@ import ( type ProvisioningV0alpha1Interface interface { RESTClient() rest.Interface + ConnectionsGetter HistoricJobsGetter JobsGetter RepositoriesGetter @@ -24,6 +25,10 @@ type ProvisioningV0alpha1Client struct { restClient rest.Interface } +func (c *ProvisioningV0alpha1Client) Connections(namespace string) ConnectionInterface { + return newConnections(c, namespace) +} + func (c *ProvisioningV0alpha1Client) HistoricJobs(namespace string) HistoricJobInterface { return newHistoricJobs(c, namespace) } diff --git a/apps/provisioning/pkg/generated/informers/externalversions/generic.go b/apps/provisioning/pkg/generated/informers/externalversions/generic.go index 4a62aab044a..8429b75d959 100644 --- a/apps/provisioning/pkg/generated/informers/externalversions/generic.go +++ b/apps/provisioning/pkg/generated/informers/externalversions/generic.go @@ -39,6 +39,8 @@ func (f *genericInformer) Lister() cache.GenericLister { func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { // Group=provisioning.grafana.app, Version=v0alpha1 + case v0alpha1.SchemeGroupVersion.WithResource("connections"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Provisioning().V0alpha1().Connections().Informer()}, nil case v0alpha1.SchemeGroupVersion.WithResource("historicjobs"): return &genericInformer{resource: resource.GroupResource(), informer: f.Provisioning().V0alpha1().HistoricJobs().Informer()}, nil case v0alpha1.SchemeGroupVersion.WithResource("jobs"): diff --git a/apps/provisioning/pkg/generated/informers/externalversions/provisioning/v0alpha1/connection.go b/apps/provisioning/pkg/generated/informers/externalversions/provisioning/v0alpha1/connection.go new file mode 100644 index 00000000000..d8fa071219f --- /dev/null +++ b/apps/provisioning/pkg/generated/informers/externalversions/provisioning/v0alpha1/connection.go @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by informer-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + context "context" + time "time" + + apisprovisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + versioned "github.com/grafana/grafana/apps/provisioning/pkg/generated/clientset/versioned" + internalinterfaces "github.com/grafana/grafana/apps/provisioning/pkg/generated/informers/externalversions/internalinterfaces" + provisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ConnectionInformer provides access to a shared informer and lister for +// Connections. +type ConnectionInformer interface { + Informer() cache.SharedIndexInformer + Lister() provisioningv0alpha1.ConnectionLister +} + +type connectionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewConnectionInformer constructs a new informer for Connection type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewConnectionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredConnectionInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredConnectionInformer constructs a new informer for Connection type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredConnectionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ProvisioningV0alpha1().Connections(namespace).List(context.Background(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ProvisioningV0alpha1().Connections(namespace).Watch(context.Background(), options) + }, + ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ProvisioningV0alpha1().Connections(namespace).List(ctx, options) + }, + WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ProvisioningV0alpha1().Connections(namespace).Watch(ctx, options) + }, + }, + &apisprovisioningv0alpha1.Connection{}, + resyncPeriod, + indexers, + ) +} + +func (f *connectionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredConnectionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *connectionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&apisprovisioningv0alpha1.Connection{}, f.defaultInformer) +} + +func (f *connectionInformer) Lister() provisioningv0alpha1.ConnectionLister { + return provisioningv0alpha1.NewConnectionLister(f.Informer().GetIndexer()) +} diff --git a/apps/provisioning/pkg/generated/informers/externalversions/provisioning/v0alpha1/interface.go b/apps/provisioning/pkg/generated/informers/externalversions/provisioning/v0alpha1/interface.go index cbe2fcefaf3..1a1908ab5f3 100644 --- a/apps/provisioning/pkg/generated/informers/externalversions/provisioning/v0alpha1/interface.go +++ b/apps/provisioning/pkg/generated/informers/externalversions/provisioning/v0alpha1/interface.go @@ -10,6 +10,8 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { + // Connections returns a ConnectionInformer. + Connections() ConnectionInformer // HistoricJobs returns a HistoricJobInformer. HistoricJobs() HistoricJobInformer // Jobs returns a JobInformer. @@ -29,6 +31,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } +// Connections returns a ConnectionInformer. +func (v *version) Connections() ConnectionInformer { + return &connectionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // HistoricJobs returns a HistoricJobInformer. func (v *version) HistoricJobs() HistoricJobInformer { return &historicJobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1/connection.go b/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1/connection.go new file mode 100644 index 00000000000..a12902c2bea --- /dev/null +++ b/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1/connection.go @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +// Code generated by lister-gen. DO NOT EDIT. + +package v0alpha1 + +import ( + provisioningv0alpha1 "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// ConnectionLister helps list Connections. +// All objects returned here must be treated as read-only. +type ConnectionLister interface { + // List lists all Connections in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*provisioningv0alpha1.Connection, err error) + // Connections returns an object that can list and get Connections. + Connections(namespace string) ConnectionNamespaceLister + ConnectionListerExpansion +} + +// connectionLister implements the ConnectionLister interface. +type connectionLister struct { + listers.ResourceIndexer[*provisioningv0alpha1.Connection] +} + +// NewConnectionLister returns a new ConnectionLister. +func NewConnectionLister(indexer cache.Indexer) ConnectionLister { + return &connectionLister{listers.New[*provisioningv0alpha1.Connection](indexer, provisioningv0alpha1.Resource("connection"))} +} + +// Connections returns an object that can list and get Connections. +func (s *connectionLister) Connections(namespace string) ConnectionNamespaceLister { + return connectionNamespaceLister{listers.NewNamespaced[*provisioningv0alpha1.Connection](s.ResourceIndexer, namespace)} +} + +// ConnectionNamespaceLister helps list and get Connections. +// All objects returned here must be treated as read-only. +type ConnectionNamespaceLister interface { + // List lists all Connections in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*provisioningv0alpha1.Connection, err error) + // Get retrieves the Connection from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*provisioningv0alpha1.Connection, error) + ConnectionNamespaceListerExpansion +} + +// connectionNamespaceLister implements the ConnectionNamespaceLister +// interface. +type connectionNamespaceLister struct { + listers.ResourceIndexer[*provisioningv0alpha1.Connection] +} diff --git a/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1/expansion_generated.go b/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1/expansion_generated.go index 7f0649542b3..4d840b6e2db 100644 --- a/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1/expansion_generated.go +++ b/apps/provisioning/pkg/generated/listers/provisioning/v0alpha1/expansion_generated.go @@ -4,6 +4,14 @@ package v0alpha1 +// ConnectionListerExpansion allows custom methods to be added to +// ConnectionLister. +type ConnectionListerExpansion interface{} + +// ConnectionNamespaceListerExpansion allows custom methods to be added to +// ConnectionNamespaceLister. +type ConnectionNamespaceListerExpansion interface{} + // HistoricJobListerExpansion allows custom methods to be added to // HistoricJobLister. type HistoricJobListerExpansion interface{} diff --git a/apps/provisioning/pkg/jobs/validator_test.go b/apps/provisioning/pkg/jobs/validator_test.go index fdd29598ebc..172e1929e1e 100644 --- a/apps/provisioning/pkg/jobs/validator_test.go +++ b/apps/provisioning/pkg/jobs/validator_test.go @@ -384,8 +384,7 @@ func TestValidateJob(t *testing.T) { Action: provisioning.JobActionMigrate, Repository: "test-repo", Migrate: &provisioning.MigrateJobOptions{ - History: true, - Message: "Migrate from legacy", + Message: "Migrate from unified", }, }, }, diff --git a/apps/provisioning/pkg/repository/git/repository.go b/apps/provisioning/pkg/repository/git/repository.go index 82d5ca6bd1d..bac3bd6d0a6 100644 --- a/apps/provisioning/pkg/repository/git/repository.go +++ b/apps/provisioning/pkg/repository/git/repository.go @@ -238,6 +238,8 @@ func (r *gitRepository) Read(ctx context.Context, filePath, ref string) (*reposi // Check if the path represents a directory if safepath.IsDir(filePath) { + // Strip trailing slash for git tree lookup to avoid empty path components + finalPath = strings.TrimSuffix(finalPath, "/") tree, err := r.client.GetTreeByPath(ctx, commit.Tree, finalPath) if err != nil { if errors.Is(err, nanogit.ErrObjectNotFound) { diff --git a/apps/provisioning/pkg/repository/tester.go b/apps/provisioning/pkg/repository/tester.go index 6bd65443d92..14290d0514b 100644 --- a/apps/provisioning/pkg/repository/tester.go +++ b/apps/provisioning/pkg/repository/tester.go @@ -23,7 +23,13 @@ func NewSimpleRepositoryTester(validator RepositoryValidator) SimpleRepositoryTe // TestRepository validates the repository and then runs a health check func (t *SimpleRepositoryTester) TestRepository(ctx context.Context, repo Repository) (*provisioning.TestResults, error) { - errors := t.validator.ValidateRepository(repo) + // Determine if this is a CREATE or UPDATE operation + // If the repository has been observed by the controller (ObservedGeneration > 0), + // it's an existing repository and we should treat it as UPDATE + cfg := repo.Config() + isCreate := cfg.Status.ObservedGeneration == 0 + + errors := t.validator.ValidateRepository(repo, isCreate) if len(errors) > 0 { rsp := &provisioning.TestResults{ Code: http.StatusUnprocessableEntity, // Invalid diff --git a/apps/provisioning/pkg/repository/validator.go b/apps/provisioning/pkg/repository/validator.go index 73198f0d7ee..46ba81f8cbd 100644 --- a/apps/provisioning/pkg/repository/validator.go +++ b/apps/provisioning/pkg/repository/validator.go @@ -32,7 +32,9 @@ func NewValidator(minSyncInterval time.Duration, allowedTargets []provisioning.S } // ValidateRepository solely does configuration checks on the repository object. It does not run a health check or compare against existing repositories. -func (v *RepositoryValidator) ValidateRepository(repo Repository) field.ErrorList { +// isCreate indicates whether this is a CREATE operation (true) or UPDATE operation (false). +// When isCreate is false, allowedTargets validation is skipped to allow existing repositories to continue working. +func (v *RepositoryValidator) ValidateRepository(repo Repository, isCreate bool) field.ErrorList { list := repo.Validate() cfg := repo.Config() @@ -44,7 +46,7 @@ func (v *RepositoryValidator) ValidateRepository(repo Repository) field.ErrorLis if cfg.Spec.Sync.Target == "" { list = append(list, field.Required(field.NewPath("spec", "sync", "target"), "The target type is required when sync is enabled")) - } else if !slices.Contains(v.allowedTargets, cfg.Spec.Sync.Target) { + } else if isCreate && !slices.Contains(v.allowedTargets, cfg.Spec.Sync.Target) { list = append(list, field.Invalid( field.NewPath("spec", "target"), diff --git a/apps/provisioning/pkg/repository/validator_test.go b/apps/provisioning/pkg/repository/validator_test.go index cb8b726a9bf..75980733e17 100644 --- a/apps/provisioning/pkg/repository/validator_test.go +++ b/apps/provisioning/pkg/repository/validator_test.go @@ -303,7 +303,8 @@ func TestValidateRepository(t *testing.T) { validator := NewValidator(10*time.Second, []provisioning.SyncTargetType{provisioning.SyncTargetTypeFolder}, false) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - errors := validator.ValidateRepository(tt.repository) + // Tests validate new configurations, so always pass isCreate=true + errors := validator.ValidateRepository(tt.repository, true) require.Len(t, errors, tt.expectedErrs) if tt.validateError != nil { tt.validateError(t, errors) diff --git a/apps/quotas/Makefile b/apps/quotas/Makefile new file mode 100644 index 00000000000..230bfd4149a --- /dev/null +++ b/apps/quotas/Makefile @@ -0,0 +1,9 @@ +include ../sdk.mk + +.PHONY: generate # Run Grafana App SDK code generation +generate: install-app-sdk update-app-sdk + @$(APP_SDK_BIN) generate \ + --source=./kinds/ \ + --gogenpath=./pkg/apis \ + --grouping=group \ + --defencoding=none \ No newline at end of file diff --git a/apps/investigations/go.mod b/apps/quotas/go.mod similarity index 58% rename from apps/investigations/go.mod rename to apps/quotas/go.mod index 3844fec2689..857521f2c57 100644 --- a/apps/investigations/go.mod +++ b/apps/quotas/go.mod @@ -1,17 +1,17 @@ -module github.com/grafana/grafana/apps/investigations +module github.com/grafana/grafana/apps/quotas -go 1.25.5 +go 1.25.3 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - k8s.io/apimachinery v0.34.2 - k8s.io/klog/v2 v2.130.1 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -21,23 +21,22 @@ require ( github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.48.3 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -50,42 +49,43 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/investigations/go.sum b/apps/quotas/go.sum similarity index 75% rename from apps/investigations/go.sum rename to apps/quotas/go.sum index 3df8e8b5ebe..6bbf64cb454 100644 --- a/apps/investigations/go.sum +++ b/apps/quotas/go.sum @@ -2,6 +2,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -25,12 +26,16 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -41,6 +46,7 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -48,11 +54,21 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= 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/grafana/grafana-app-sdk v0.48.2 h1:CQQDhwo1fWaXQVKvxxOcK6azbuY3E2TgJHNAZlYYn7U= +github.com/grafana/grafana-app-sdk v0.48.2/go.mod h1:LDOvQ7OOyHLcXdSa0InATCa5OMoYAd6E1+rGLrMgHuk= +github.com/grafana/grafana-app-sdk v0.48.4 h1:t9r+Y6E7D832ZxQ2c1n0lp6cvsYKhhrAodVYzE1y0s0= +github.com/grafana/grafana-app-sdk v0.48.4/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= github.com/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +github.com/grafana/grafana-app-sdk v0.48.7/go.mod h1:DWsaaH39ZMHwSOSoUBaeW8paMrRaYsjRYlLwCJYd78k= +github.com/grafana/grafana-app-sdk/logging v0.48.1 h1:veM0X5LAPyN3KsDLglWjIofndbGuf7MqnrDuDN+F/Ng= +github.com/grafana/grafana-app-sdk/logging v0.48.1/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= +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/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= @@ -75,6 +91,7 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -106,12 +123,14 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -124,29 +143,41 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= +go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -165,24 +196,30 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -199,14 +236,22 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= +google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 h1:d8Nakh1G+ur7+P3GcMjpRDEkoLUcLW2iU92XVqR+XMQ= +google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8 h1:mepRgnBZa07I4TRuomDE4sTIYieg/osKmzIf4USdWS4= +google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797 h1:CirRxTOwnRWVLKzDNrs0CXAaVozJoR4G9xvdRecrdpk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A= +google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -216,25 +261,22 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/structured-merge-diff/v6 v6.3.1/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/apps/quotas/kinds/cue.mod/module.cue b/apps/quotas/kinds/cue.mod/module.cue new file mode 100644 index 00000000000..6e70f424d2e --- /dev/null +++ b/apps/quotas/kinds/cue.mod/module.cue @@ -0,0 +1,2 @@ +module: "github.com/grafana/grafana/apps/quotas/kinds" +language: version: "v0.8.2" diff --git a/apps/quotas/kinds/manifest.cue b/apps/quotas/kinds/manifest.cue new file mode 100644 index 00000000000..8f799ff070c --- /dev/null +++ b/apps/quotas/kinds/manifest.cue @@ -0,0 +1,92 @@ +package kinds + +manifest: { + // appName is the unique name of your app. It is used to reference the app from other config objects, + // and to generate the group used by your app in the app platform API. + appName: "quotas" + // groupOverride can be used to specify a non-appName-based API group. + // By default, an app's API group is LOWER(REPLACE(appName, '-', '')).ext.grafana.com, + // but there are cases where this needs to be changed. + // Keep in mind that changing this after an app is deployed can cause problems with clients and/or kind data. + groupOverride: "quotas.grafana.app" + + // versions is a map of versions supported by your app. Version names should follow the format "v" or + // "v(alpha|beta)". Each version contains the kinds your app manages for that version. + // If your app needs access to kinds managed by another app, use permissions.accessKinds to allow your app access. + versions: { + "v0alpha1": v0alpha1 + } + // extraPermissions contains any additional permissions your app may require to function. + // Your app will always have all permissions for each kind it manages (the items defined in 'kinds'). + extraPermissions: { + // If your app needs access to additional kinds supplied by other apps, you can list them here + accessKinds: [ + // Here is an example for your app accessing the playlist kind for reads and watch + // { + // group: "playlist.grafana.app" + // resource: "playlists" + // actions: ["get","list","watch"] + // } + ] + } +} + +// v1alpha1 is the v1alpha1 version of the app's API. +// It includes kinds which the v1alpha1 API serves, and (future) custom routes served globally from the v1alpha1 version. +v0alpha1: { + // kinds is the list of kinds served by this version + kinds: [] + // [OPTIONAL] + // served indicates whether this particular version is served by the API server. + // served should be set to false before a version is removed from the manifest entirely. + // served defaults to true if not present. + served: true + + routes: { + // namespaced contains namespace-scoped resource routes for the version, + // which are exposed as HTTP handlers on '/namespaces//'. + namespaced: { + "/usage": { + "GET": { + response: { + namespace: string + resource: string + group: string + usage: int64 + limit: int64 + } + request: { + query: { + group: string + resource: string + } + } + } + } + } + } + + // [OPTIONAL] + // Codegen is a trait that tells the grafana-app-sdk, or other code generation tooling, how to process this kind. + // If not present, default values within the codegen trait are used. + // If you wish to specify codegen per-version, put this section in the version's object + // (for example, v1alpha1) instead. + codegen: { + // [OPTIONAL] + // ts contains TypeScript code generation properties for the kind + ts: { + // [OPTIONAL] + // enabled indicates whether the CLI should generate front-end TypeScript code for the kind. + // Defaults to true if not present. + enabled: true + } + // [OPTIONAL] + // go contains go code generation properties for the kind + go: { + // [OPTIONAL] + // enabled indicates whether the CLI should generate back-end go code for the kind. + // Defaults to true if not present. + enabled: true + } + } +} diff --git a/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_request_params_object_gen.go b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_request_params_object_gen.go new file mode 100644 index 00000000000..b19b40d5e02 --- /dev/null +++ b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_request_params_object_gen.go @@ -0,0 +1,33 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +type GetUsageRequestParamsObject struct { + metav1.TypeMeta `json:",inline"` + GetUsageRequestParams `json:",inline"` +} + +func NewGetUsageRequestParamsObject() *GetUsageRequestParamsObject { + return &GetUsageRequestParamsObject{} +} + +func (o *GetUsageRequestParamsObject) DeepCopyObject() runtime.Object { + dst := NewGetUsageRequestParamsObject() + o.DeepCopyInto(dst) + return dst +} + +func (o *GetUsageRequestParamsObject) DeepCopyInto(dst *GetUsageRequestParamsObject) { + dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion + dst.TypeMeta.Kind = o.TypeMeta.Kind + dstGetUsageRequestParams := GetUsageRequestParams{} + _ = resource.CopyObjectInto(&dstGetUsageRequestParams, &o.GetUsageRequestParams) +} + +var _ runtime.Object = NewGetUsageRequestParamsObject() diff --git a/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_request_params_types_gen.go b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_request_params_types_gen.go new file mode 100644 index 00000000000..45394a7f20f --- /dev/null +++ b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_request_params_types_gen.go @@ -0,0 +1,13 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +type GetUsageRequestParams struct { + Group string `json:"group"` + Resource string `json:"resource"` +} + +// NewGetUsageRequestParams creates a new GetUsageRequestParams object. +func NewGetUsageRequestParams() *GetUsageRequestParams { + return &GetUsageRequestParams{} +} diff --git a/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_response_body_types_gen.go b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_response_body_types_gen.go new file mode 100644 index 00000000000..eb87d022edd --- /dev/null +++ b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_response_body_types_gen.go @@ -0,0 +1,17 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// +k8s:openapi-gen=true +type GetUsageBody struct { + Namespace string `json:"namespace"` + Resource string `json:"resource"` + Group string `json:"group"` + Usage int64 `json:"usage"` + Limit int64 `json:"limit"` +} + +// NewGetUsageBody creates a new GetUsageBody object. +func NewGetUsageBody() *GetUsageBody { + return &GetUsageBody{} +} diff --git a/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_response_object_types_gen.go b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_response_object_types_gen.go new file mode 100644 index 00000000000..87d6be2e587 --- /dev/null +++ b/apps/quotas/pkg/apis/quotas/v0alpha1/getusage_response_object_types_gen.go @@ -0,0 +1,37 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// +k8s:openapi-gen=true +type GetUsage struct { + metav1.TypeMeta `json:",inline"` + GetUsageBody `json:",inline"` +} + +func NewGetUsage() *GetUsage { + return &GetUsage{} +} + +func (t *GetUsageBody) DeepCopyInto(dst *GetUsageBody) { + _ = resource.CopyObjectInto(dst, t) +} + +func (o *GetUsage) DeepCopyObject() runtime.Object { + dst := NewGetUsage() + o.DeepCopyInto(dst) + return dst +} + +func (o *GetUsage) DeepCopyInto(dst *GetUsage) { + dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion + dst.TypeMeta.Kind = o.TypeMeta.Kind + o.GetUsageBody.DeepCopyInto(&dst.GetUsageBody) +} + +var _ runtime.Object = NewGetUsage() diff --git a/apps/quotas/pkg/apis/quotas_manifest.go b/apps/quotas/pkg/apis/quotas_manifest.go new file mode 100644 index 00000000000..e72524d59f3 --- /dev/null +++ b/apps/quotas/pkg/apis/quotas_manifest.go @@ -0,0 +1,213 @@ +// +// This file is generated by grafana-app-sdk +// DO NOT EDIT +// + +package apis + +import ( + "fmt" + "strings" + + "github.com/grafana/grafana-app-sdk/app" + "github.com/grafana/grafana-app-sdk/resource" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/kube-openapi/pkg/spec3" + "k8s.io/kube-openapi/pkg/validation/spec" + + v0alpha1 "github.com/grafana/grafana/apps/quotas/pkg/apis/quotas/v0alpha1" +) + +var appManifestData = app.ManifestData{ + AppName: "quotas", + Group: "quotas.grafana.app", + PreferredVersion: "v0alpha1", + Versions: []app.ManifestVersion{ + { + Name: "v0alpha1", + Served: true, + Kinds: []app.ManifestVersionKind{}, + Routes: app.ManifestVersionRoutes{ + Namespaced: map[string]spec3.PathProps{ + "/usage": { + Get: &spec3.Operation{ + OperationProps: spec3.OperationProps{ + + OperationId: "getUsage", + + Parameters: []*spec3.Parameter{ + + { + ParameterProps: spec3.ParameterProps{ + Name: "group", + In: "query", + Required: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + }, + }, + + { + ParameterProps: spec3.ParameterProps{ + Name: "resource", + In: "query", + Required: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + }, + }, + }, + + Responses: &spec3.Responses{ + ResponsesProps: spec3.ResponsesProps{ + Default: &spec3.Response{ + ResponseProps: spec3.ResponseProps{ + Description: "Default OK response", + Content: map[string]*spec3.MediaType{ + "application/json": { + MediaTypeProps: spec3.MediaTypeProps{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + }, + }, + "group": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "kind": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + }, + }, + "limit": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + }, + }, + "namespace": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "resource": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + }, + }, + "usage": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + }, + }, + }, + Required: []string{ + "namespace", + "resource", + "group", + "usage", + "limit", + "apiVersion", + "kind", + }, + }}, + }}, + }, + }, + }, + }}, + }, + }, + }, + }, + Cluster: map[string]spec3.PathProps{}, + Schemas: map[string]spec.Schema{}, + }, + }, + }, +} + +func LocalManifest() app.Manifest { + return app.NewEmbeddedManifest(appManifestData) +} + +func RemoteManifest() app.Manifest { + return app.NewAPIServerManifest("quotas") +} + +var kindVersionToGoType = map[string]resource.Kind{} + +// ManifestGoTypeAssociator returns the associated resource.Kind instance for a given Kind and Version, if one exists. +// If there is no association for the provided Kind and Version, exists will return false. +func ManifestGoTypeAssociator(kind, version string) (goType resource.Kind, exists bool) { + goType, exists = kindVersionToGoType[fmt.Sprintf("%s/%s", kind, version)] + return goType, exists +} + +var customRouteToGoResponseType = map[string]any{ + "v0alpha1||/usage|GET": v0alpha1.GetUsage{}, +} + +// ManifestCustomRouteResponsesAssociator returns the associated response go type for a given kind, version, custom route path, and method, if one exists. +// kind may be empty for custom routes which are not kind subroutes. Leading slashes are removed from subroute paths. +// If there is no association for the provided kind, version, custom route path, and method, exists will return false. +// Resource routes (those without a kind) should prefix their route with "/" if the route is namespaced (otherwise the route is assumed to be cluster-scope) +func ManifestCustomRouteResponsesAssociator(kind, version, path, verb string) (goType any, exists bool) { + if len(path) > 0 && path[0] == '/' { + path = path[1:] + } + goType, exists = customRouteToGoResponseType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] + return goType, exists +} + +var customRouteToGoParamsType = map[string]runtime.Object{} + +func ManifestCustomRouteQueryAssociator(kind, version, path, verb string) (goType runtime.Object, exists bool) { + if len(path) > 0 && path[0] == '/' { + path = path[1:] + } + goType, exists = customRouteToGoParamsType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] + return goType, exists +} + +var customRouteToGoRequestBodyType = map[string]any{} + +func ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb string) (goType any, exists bool) { + if len(path) > 0 && path[0] == '/' { + path = path[1:] + } + goType, exists = customRouteToGoRequestBodyType[fmt.Sprintf("%s|%s|%s|%s", version, kind, path, strings.ToUpper(verb))] + return goType, exists +} + +type GoTypeAssociator struct{} + +func NewGoTypeAssociator() *GoTypeAssociator { + return &GoTypeAssociator{} +} + +func (g *GoTypeAssociator) KindToGoType(kind, version string) (goType resource.Kind, exists bool) { + return ManifestGoTypeAssociator(kind, version) +} +func (g *GoTypeAssociator) CustomRouteReturnGoType(kind, version, path, verb string) (goType any, exists bool) { + return ManifestCustomRouteResponsesAssociator(kind, version, path, verb) +} +func (g *GoTypeAssociator) CustomRouteQueryGoType(kind, version, path, verb string) (goType runtime.Object, exists bool) { + return ManifestCustomRouteQueryAssociator(kind, version, path, verb) +} +func (g *GoTypeAssociator) CustomRouteRequestBodyGoType(kind, version, path, verb string) (goType any, exists bool) { + return ManifestCustomRouteRequestBodyAssociator(kind, version, path, verb) +} diff --git a/apps/quotas/pkg/app/app.go b/apps/quotas/pkg/app/app.go new file mode 100644 index 00000000000..d4862661b60 --- /dev/null +++ b/apps/quotas/pkg/app/app.go @@ -0,0 +1,123 @@ +package app + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "github.com/grafana/grafana-app-sdk/app" + "github.com/grafana/grafana-app-sdk/logging" + "github.com/grafana/grafana-app-sdk/operator" + "github.com/grafana/grafana-app-sdk/resource" + "github.com/grafana/grafana/pkg/storage/unified/resourcepb" + + unifiedStorage "github.com/grafana/grafana/pkg/storage/unified/resource" + + "github.com/grafana/grafana-app-sdk/simple" + quotasv0alpha1 "github.com/grafana/grafana/apps/quotas/pkg/apis/quotas/v0alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +type QuotasAppConfig struct { + ResourceClient unifiedStorage.ResourceClient +} + +type QuotasHandler struct { + ResourceClient unifiedStorage.ResourceClient +} + +func NewQuotasHandler(cfg *QuotasAppConfig) *QuotasHandler { + return &QuotasHandler{ + ResourceClient: cfg.ResourceClient, + } +} + +// GetQuota handles requests for the GET /usage resource route +func (h *QuotasHandler) GetQuota(ctx context.Context, writer app.CustomRouteResponseWriter, request *app.CustomRouteRequest) error { + if !request.URL.Query().Has("group") { + // TODO its returning a 500 instead of 400 bad request + writer.WriteHeader(http.StatusBadRequest) + return fmt.Errorf("missing required query parameters: group") + } + if !request.URL.Query().Has("resource") { + writer.WriteHeader(http.StatusBadRequest) + return fmt.Errorf("missing required query parameters: resource") + } + group := request.URL.Query().Get("group") + res := request.URL.Query().Get("resource") + + quotaReq := &resourcepb.QuotaUsageRequest{ + Key: &resourcepb.ResourceKey{ + Namespace: request.ResourceIdentifier.Namespace, + Group: group, + Resource: res, + }, + } + quota, err := h.ResourceClient.GetQuotaUsage(ctx, quotaReq) + if err != nil { + return err + } + + writer.Header().Set("Content-Type", "application/json") + return json.NewEncoder(writer).Encode(quotasv0alpha1.GetUsage{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "quotas.grafana.com/v0alpha1", + Kind: "Quotas", + }, + GetUsageBody: quotasv0alpha1.GetUsageBody{ + Namespace: request.ResourceIdentifier.Namespace, + Group: group, + Resource: res, + Usage: quota.Usage, + Limit: quota.Limit, + }, + }) +} + +func New(cfg app.Config) (app.App, error) { + appConfig, ok := cfg.SpecificConfig.(*QuotasAppConfig) + if !ok { + return nil, fmt.Errorf("expected QuotasAppConfig but got %T", cfg.SpecificConfig) + } + handler := NewQuotasHandler(appConfig) + + simpleConfig := simple.AppConfig{ + Name: "quotas", + KubeConfig: cfg.KubeConfig, + InformerConfig: simple.AppInformerConfig{ + InformerOptions: operator.InformerOptions{ + ErrorHandler: func(ctx context.Context, err error) { + logging.FromContext(ctx).Error("Informer processing error", "error", err) + }, + }, + }, + ManagedKinds: []simple.AppManagedKind{}, + VersionedCustomRoutes: map[string]simple.AppVersionRouteHandlers{ + "v0alpha1": { + { + Namespaced: true, + Path: "usage", + Method: "GET", + }: handler.GetQuota, + }, + }, + } + + a, err := simple.NewApp(simpleConfig) + if err != nil { + return nil, err + } + + err = a.ValidateManifest(cfg.ManifestData) + if err != nil { + return nil, err + } + + return a, nil +} + +func GetKinds() map[schema.GroupVersion][]resource.Kind { + return map[schema.GroupVersion][]resource.Kind{} +} diff --git a/apps/quotas/pkg/app/app_test.go b/apps/quotas/pkg/app/app_test.go new file mode 100644 index 00000000000..252c2c4e240 --- /dev/null +++ b/apps/quotas/pkg/app/app_test.go @@ -0,0 +1,71 @@ +package app + +import ( + "context" + "net/http/httptest" + "net/url" + "testing" + + "github.com/grafana/grafana-app-sdk/app" + "github.com/grafana/grafana/pkg/storage/unified/resource" + "github.com/grafana/grafana/pkg/storage/unified/resourcepb" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" +) + +func TestGetQuota(t *testing.T) { + t.Run("will return error when resource param is missing", func(t *testing.T) { + clientMock := resource.NewMockResourceClient(t) + handler := NewQuotasHandler(&QuotasAppConfig{ + ResourceClient: clientMock, + }) + url, err := url.Parse("http://localhost:3000/apis/quotas.grafana.app/v0alpha1/namespaces/stacks-1/usage?group=dashboard.grafana.app") + require.NoError(t, err) + req := &app.CustomRouteRequest{ + URL: url, + Method: "GET", + } + recorder := &httptest.ResponseRecorder{} + err = handler.GetQuota(context.Background(), recorder, req) + require.Error(t, err) + }) + + t.Run("will return error when group param is missing", func(t *testing.T) { + clientMock := resource.NewMockResourceClient(t) + handler := NewQuotasHandler(&QuotasAppConfig{ + ResourceClient: clientMock, + }) + url, err := url.Parse("http://localhost:3000/apis/quotas.grafana.app/v0alpha1/namespaces/stacks-1/usage?resource=dashboards") + require.NoError(t, err) + req := &app.CustomRouteRequest{ + URL: url, + Method: "GET", + } + recorder := &httptest.ResponseRecorder{} + err = handler.GetQuota(context.Background(), recorder, req) + require.Error(t, err) + }) + + t.Run("will return quotas response when params are valid", func(t *testing.T) { + clientMock := resource.NewMockResourceClient(t) + clientMock.On("GetQuotaUsage", mock.Anything, mock.Anything, mock.Anything).Return(&resourcepb.QuotaUsageResponse{ + Error: nil, + Usage: 1, + Limit: 2, + }, nil) + handler := NewQuotasHandler(&QuotasAppConfig{ + ResourceClient: clientMock, + }) + url, err := url.Parse("http://localhost:3000/apis/quotas.grafana.app/v0alpha1/namespaces/stacks-1/usage?group=dashboard.grafana.app&resource=dashboards") + require.NoError(t, err) + req := &app.CustomRouteRequest{ + URL: url, + Method: "GET", + } + recorder := &httptest.ResponseRecorder{} + err = handler.GetQuota(context.Background(), recorder, req) + require.NoError(t, err) + + require.Equal(t, 200, recorder.Code) + }) +} diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/investigation_object_gen.ts b/apps/quotas/plugin/src/generated/quota/v0alpha1/quota_object_gen.ts similarity index 97% rename from apps/investigations/plugin/src/generated/investigation/v0alpha1/investigation_object_gen.ts rename to apps/quotas/plugin/src/generated/quota/v0alpha1/quota_object_gen.ts index 3c7cf0874f8..70f306a1b08 100644 --- a/apps/investigations/plugin/src/generated/investigation/v0alpha1/investigation_object_gen.ts +++ b/apps/quotas/plugin/src/generated/quota/v0alpha1/quota_object_gen.ts @@ -40,7 +40,7 @@ export interface ManagedFieldsEntry { subresource?: string; } -export interface Investigation { +export interface Quota { kind: string; apiVersion: string; metadata: Metadata; diff --git a/apps/quotas/plugin/src/generated/quota/v0alpha1/types.metadata.gen.ts b/apps/quotas/plugin/src/generated/quota/v0alpha1/types.metadata.gen.ts new file mode 100644 index 00000000000..4377f3c1d08 --- /dev/null +++ b/apps/quotas/plugin/src/generated/quota/v0alpha1/types.metadata.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +export interface Metadata { + updateTimestamp: string; + createdBy: string; + uid: string; + creationTimestamp: string; + deletionTimestamp?: string; + finalizers: string[]; + resourceVersion: string; + generation: number; + updatedBy: string; + labels: Record; +} + +export const defaultMetadata = (): Metadata => ({ + updateTimestamp: "", + createdBy: "", + uid: "", + creationTimestamp: "", + finalizers: [], + resourceVersion: "", + generation: 0, + updatedBy: "", + labels: {}, +}); + diff --git a/apps/quotas/plugin/src/generated/quota/v0alpha1/types.spec.gen.ts b/apps/quotas/plugin/src/generated/quota/v0alpha1/types.spec.gen.ts new file mode 100644 index 00000000000..9209753fa64 --- /dev/null +++ b/apps/quotas/plugin/src/generated/quota/v0alpha1/types.spec.gen.ts @@ -0,0 +1,14 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface Spec { + count: string; + limit: string; + kind: string; +} + +export const defaultSpec = (): Spec => ({ + count: "", + limit: "", + kind: "", +}); + diff --git a/apps/quotas/plugin/src/generated/quota/v0alpha1/types.status.gen.ts b/apps/quotas/plugin/src/generated/quota/v0alpha1/types.status.gen.ts new file mode 100644 index 00000000000..01be8df7961 --- /dev/null +++ b/apps/quotas/plugin/src/generated/quota/v0alpha1/types.status.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface OperatorState { + // lastEvaluation is the ResourceVersion last evaluated + lastEvaluation: string; + // state describes the state of the lastEvaluation. + // It is limited to three possible states for machine evaluation. + state: "success" | "in_progress" | "failed"; + // descriptiveState is an optional more descriptive state field which has no requirements on format + descriptiveState?: string; + // details contains any extra information that is operator-specific + details?: Record; +} + +export const defaultOperatorState = (): OperatorState => ({ + lastEvaluation: "", + state: "success", +}); + +export interface Status { + // operatorStates is a map of operator ID to operator state evaluations. + // Any operator which consumes this kind SHOULD add its state evaluation information to this field. + operatorStates?: Record; + // additionalFields is reserved for future use + additionalFields?: Record; +} + +export const defaultStatus = (): Status => ({ +}); + diff --git a/apps/scope/go.mod b/apps/scope/go.mod index c54a582379f..ed380519e75 100644 --- a/apps/scope/go.mod +++ b/apps/scope/go.mod @@ -4,8 +4,8 @@ go 1.25.5 require ( github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251007081214-26e147d01f0a - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( @@ -13,15 +13,24 @@ require ( github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/josharian/intern v1.0.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -30,14 +39,15 @@ require ( github.com/x448/float16 v0.8.4 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/text v0.31.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect ) diff --git a/apps/scope/go.sum b/apps/scope/go.sum index 5df9519a7e2..19f7f445bc6 100644 --- a/apps/scope/go.sum +++ b/apps/scope/go.sum @@ -1,3 +1,4 @@ +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -8,44 +9,71 @@ github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sa github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251007081214-26e147d01f0a h1:L7xgV9mP6MRF3L2/vDOjNR7heaBPbXPMGTDN9/jXSFQ= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251007081214-26e147d01f0a/go.mod h1:OK8NwS87D5YphchOcAsiIWk/feMZ0EzfAGME1Kff860= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -73,8 +101,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -83,8 +111,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -93,8 +121,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -102,16 +130,16 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/scope/pkg/apis/scope/v0alpha1/types.go b/apps/scope/pkg/apis/scope/v0alpha1/types.go index 0c323d8d14b..20414f3caf6 100644 --- a/apps/scope/pkg/apis/scope/v0alpha1/types.go +++ b/apps/scope/pkg/apis/scope/v0alpha1/types.go @@ -211,6 +211,12 @@ type ScopeNavigationSpec struct { Scope string `json:"scope"` // Used to navigate to a sub-scope of the main scope. URL will not be used if this is set. SubScope string `json:"subScope,omitempty"` + // Preload the subscope children, as soon as the ScopeNavigation is loaded. + PreLoadSubScopeChildren bool `json:"preLoadSubScopeChildren,omitempty"` + // Expands to display the subscope children when the ScopeNavigation is loaded. + ExpandOnLoad bool `json:"expandOnLoad,omitempty"` + // Makes the subscope not selectable, only serving as a way to build the tree. + DisableSubScopeSelection bool `json:"disableSubScopeSelection,omitempty"` } // Type of the item. diff --git a/apps/scope/pkg/apis/scope/v0alpha1/zz_generated.openapi.go b/apps/scope/pkg/apis/scope/v0alpha1/zz_generated.openapi.go index 50015307139..1cb72adf4b1 100644 --- a/apps/scope/pkg/apis/scope/v0alpha1/zz_generated.openapi.go +++ b/apps/scope/pkg/apis/scope/v0alpha1/zz_generated.openapi.go @@ -642,6 +642,27 @@ func schema_pkg_apis_scope_v0alpha1_ScopeNavigationSpec(ref common.ReferenceCall Format: "", }, }, + "preLoadSubScopeChildren": { + SchemaProps: spec.SchemaProps{ + Description: "Preload the subscope children, as soon as the ScopeNavigation is loaded.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "expandOnLoad": { + SchemaProps: spec.SchemaProps{ + Description: "Expands to display the subscope children when the ScopeNavigation is loaded.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "disableSubScopeSelection": { + SchemaProps: spec.SchemaProps{ + Description: "Makes the subscope not selectable, only serving as a way to build the tree.", + Type: []string{"boolean"}, + Format: "", + }, + }, }, Required: []string{"url", "scope"}, }, diff --git a/apps/sdk.mk b/apps/sdk.mk index 68cf4c1c9c9..45580f59037 100644 --- a/apps/sdk.mk +++ b/apps/sdk.mk @@ -1,4 +1,4 @@ -APP_SDK_VERSION = v0.48.5 +APP_SDK_VERSION = v0.48.7 APP_SDK_DIR = $(shell go env GOPATH)/bin/app-sdk-$(APP_SDK_VERSION) APP_SDK_BIN = $(APP_SDK_DIR)/grafana-app-sdk diff --git a/apps/secret/go.mod b/apps/secret/go.mod index a1ed48be6e7..d0da36e2e83 100644 --- a/apps/secret/go.mod +++ b/apps/secret/go.mod @@ -3,15 +3,15 @@ module github.com/grafana/grafana/apps/secret go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 + github.com/grafana/grafana-app-sdk v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250710134100-1f3dc0533caf github.com/stretchr/testify v1.11.1 go.yaml.in/yaml/v3 v3.0.4 google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 - k8s.io/apimachinery v0.34.2 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 + google.golang.org/protobuf v1.36.11 + k8s.io/apimachinery v0.34.3 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 ) require ( @@ -22,19 +22,29 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.48.3 // indirect + github.com/google/gnostic-models v0.7.1 // indirect + github.com/grafana/grafana-app-sdk/logging v0.48.7 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -45,26 +55,27 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.34.2 // indirect + k8s.io/client-go v0.34.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/secret/go.sum b/apps/secret/go.sum index 166e281f5af..6ea5dd8dfd3 100644 --- a/apps/secret/go.sum +++ b/apps/secret/go.sum @@ -16,31 +16,57 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250710134100-1f3dc0533caf h1:BBGDHffvVNLoYQlXEpbXcxE0vbpq7pm/8OWF5I+UDZg= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250710134100-1f3dc0533caf/go.mod h1:eAlOam2uWhrsEZlOoAr7XZ9hbBP7SyYGYn31/aQAPs8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -62,8 +88,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -80,8 +106,6 @@ github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletI github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -89,10 +113,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= @@ -105,24 +129,24 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= @@ -138,24 +162,24 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -168,35 +192,35 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/apps/secret/kinds/v1beta1/keeper.cue b/apps/secret/kinds/v1beta1/keeper.cue index 36e20198ab7..4ade465d1b5 100644 --- a/apps/secret/kinds/v1beta1/keeper.cue +++ b/apps/secret/kinds/v1beta1/keeper.cue @@ -30,11 +30,22 @@ KeeperSpec: { } #AWSConfig: { - accessKeyID: #CredentialValue - secretAccessKey: #CredentialValue + region: string + accessKey?: #AWSAccessKey + assumeRole?: #AWSAssumeRole kmsKeyID?: string } +#AWSAccessKey: { + accessKeyID: #CredentialValue + secretAccessKey: #CredentialValue +} + +#AWSAssumeRole: { + assumeRoleArn: string + externalID: string +} + #AzureConfig: { keyVaultName: string tenantID: string diff --git a/apps/secret/pkg/apis/secret/v1beta1/keeper_spec_gen.go b/apps/secret/pkg/apis/secret/v1beta1/keeper_spec_gen.go index 76d232465c8..806a3df8294 100644 --- a/apps/secret/pkg/apis/secret/v1beta1/keeper_spec_gen.go +++ b/apps/secret/pkg/apis/secret/v1beta1/keeper_spec_gen.go @@ -4,14 +4,26 @@ package v1beta1 // +k8s:openapi-gen=true type KeeperAWSConfig struct { - AccessKeyID KeeperCredentialValue `json:"accessKeyID"` - SecretAccessKey KeeperCredentialValue `json:"secretAccessKey"` - KmsKeyID *string `json:"kmsKeyID,omitempty"` + Region string `json:"region"` + AccessKey *KeeperAWSAccessKey `json:"accessKey,omitempty"` + AssumeRole *KeeperAWSAssumeRole `json:"assumeRole,omitempty"` + KmsKeyID *string `json:"kmsKeyID,omitempty"` } // NewKeeperAWSConfig creates a new KeeperAWSConfig object. func NewKeeperAWSConfig() *KeeperAWSConfig { - return &KeeperAWSConfig{ + return &KeeperAWSConfig{} +} + +// +k8s:openapi-gen=true +type KeeperAWSAccessKey struct { + AccessKeyID KeeperCredentialValue `json:"accessKeyID"` + SecretAccessKey KeeperCredentialValue `json:"secretAccessKey"` +} + +// NewKeeperAWSAccessKey creates a new KeeperAWSAccessKey object. +func NewKeeperAWSAccessKey() *KeeperAWSAccessKey { + return &KeeperAWSAccessKey{ AccessKeyID: *NewKeeperCredentialValue(), SecretAccessKey: *NewKeeperCredentialValue(), } @@ -36,6 +48,17 @@ func NewKeeperCredentialValue() *KeeperCredentialValue { return &KeeperCredentialValue{} } +// +k8s:openapi-gen=true +type KeeperAWSAssumeRole struct { + AssumeRoleArn string `json:"assumeRoleArn"` + ExternalID string `json:"externalID"` +} + +// NewKeeperAWSAssumeRole creates a new KeeperAWSAssumeRole object. +func NewKeeperAWSAssumeRole() *KeeperAWSAssumeRole { + return &KeeperAWSAssumeRole{} +} + // +k8s:openapi-gen=true type KeeperAzureConfig struct { KeyVaultName string `json:"keyVaultName"` diff --git a/apps/secret/pkg/apis/secret/v1beta1/keeper_type.go b/apps/secret/pkg/apis/secret/v1beta1/keeper_type.go index 0feeac75dd1..6f61acf1a77 100644 --- a/apps/secret/pkg/apis/secret/v1beta1/keeper_type.go +++ b/apps/secret/pkg/apis/secret/v1beta1/keeper_type.go @@ -12,6 +12,7 @@ const ( AzureKeeperType KeeperType = "azure" GCPKeeperType KeeperType = "gcp" HashiCorpKeeperType KeeperType = "hashicorp" + SystemKeeperType KeeperType = "system" ) func (kt KeeperType) String() string { @@ -20,9 +21,31 @@ func (kt KeeperType) String() string { // KeeperConfig is an interface that all keeper config types must implement. type KeeperConfig interface { + // Returns the name of the keeper + GetName() string Type() KeeperType } +type NamedKeeperConfig[T interface { + Type() KeeperType +}] struct { + Name string + Cfg T +} + +func NewNamedKeeperConfig[T interface { + Type() KeeperType +}](keeperName string, cfg T) *NamedKeeperConfig[T] { + return &NamedKeeperConfig[T]{Name: keeperName, Cfg: cfg} +} + +func (c *NamedKeeperConfig[T]) GetName() string { + return c.Name +} +func (c *NamedKeeperConfig[T]) Type() KeeperType { + return c.Cfg.Type() +} + func (s *KeeperSpec) GetType() KeeperType { if s.Aws != nil { return AWSKeeperType @@ -43,7 +66,7 @@ func (s *KeeperSpec) GetType() KeeperType { type SystemKeeperConfig struct{} func (*SystemKeeperConfig) Type() KeeperType { - return "system" + return SystemKeeperType } func (s *KeeperAWSConfig) Type() KeeperType { diff --git a/apps/secret/pkg/apis/secret/v1beta1/zz_openapi_gen.go b/apps/secret/pkg/apis/secret/v1beta1/zz_openapi_gen.go index 101e4bb55b3..4d295874224 100644 --- a/apps/secret/pkg/apis/secret/v1beta1/zz_openapi_gen.go +++ b/apps/secret/pkg/apis/secret/v1beta1/zz_openapi_gen.go @@ -14,6 +14,8 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.Keeper": schema_pkg_apis_secret_v1beta1_Keeper(ref), + "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAWSAccessKey": schema_pkg_apis_secret_v1beta1_KeeperAWSAccessKey(ref), + "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAWSAssumeRole": schema_pkg_apis_secret_v1beta1_KeeperAWSAssumeRole(ref), "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAWSConfig": schema_pkg_apis_secret_v1beta1_KeeperAWSConfig(ref), "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAzureConfig": schema_pkg_apis_secret_v1beta1_KeeperAzureConfig(ref), "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperCredentialValue": schema_pkg_apis_secret_v1beta1_KeeperCredentialValue(ref), @@ -79,7 +81,7 @@ func schema_pkg_apis_secret_v1beta1_Keeper(ref common.ReferenceCallback) common. } } -func schema_pkg_apis_secret_v1beta1_KeeperAWSConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_secret_v1beta1_KeeperAWSAccessKey(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -97,6 +99,65 @@ func schema_pkg_apis_secret_v1beta1_KeeperAWSConfig(ref common.ReferenceCallback Ref: ref("github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperCredentialValue"), }, }, + }, + Required: []string{"accessKeyID", "secretAccessKey"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperCredentialValue"}, + } +} + +func schema_pkg_apis_secret_v1beta1_KeeperAWSAssumeRole(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "assumeRoleArn": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "externalID": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"assumeRoleArn", "externalID"}, + }, + }, + } +} + +func schema_pkg_apis_secret_v1beta1_KeeperAWSConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "region": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "accessKey": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAWSAccessKey"), + }, + }, + "assumeRole": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAWSAssumeRole"), + }, + }, "kmsKeyID": { SchemaProps: spec.SchemaProps{ Type: []string{"string"}, @@ -104,11 +165,11 @@ func schema_pkg_apis_secret_v1beta1_KeeperAWSConfig(ref common.ReferenceCallback }, }, }, - Required: []string{"accessKeyID", "secretAccessKey"}, + Required: []string{"region"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperCredentialValue"}, + "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAWSAccessKey", "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1.KeeperAWSAssumeRole"}, } } diff --git a/apps/shorturl/go.mod b/apps/shorturl/go.mod index 4a414de5b4e..c75106d2822 100644 --- a/apps/shorturl/go.mod +++ b/apps/shorturl/go.mod @@ -3,18 +3,18 @@ module github.com/grafana/grafana/apps/shorturl go 1.25.5 require ( - github.com/grafana/grafana-app-sdk v0.48.5 - github.com/grafana/grafana-app-sdk/logging v0.48.3 + github.com/grafana/grafana-app-sdk v0.48.7 + github.com/grafana/grafana-app-sdk/logging v0.48.7 github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250915132226-585b53bc7dba - k8s.io/apimachinery v0.34.2 - k8s.io/apiserver v0.34.2 + k8s.io/apimachinery v0.34.3 + k8s.io/apiserver v0.34.3 k8s.io/klog/v2 v2.130.1 - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e ) require ( github.com/beorn7/perks v1.0.1 // indirect - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -25,13 +25,23 @@ require ( github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect - github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect + github.com/go-openapi/swag v0.25.4 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect github.com/go-test/deep v1.1.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/google/uuid v1.6.0 // indirect @@ -43,7 +53,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -57,42 +67,42 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.23.2 // indirect github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.67.3 // indirect - github.com/prometheus/procfs v0.16.1 // indirect + github.com/prometheus/common v0.67.4 // indirect + github.com/prometheus/procfs v0.19.2 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect + go.opentelemetry.io/otel/sdk v1.39.0 // indirect + go.opentelemetry.io/otel/trace v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.33.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/oauth2 v0.34.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/term v0.38.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/time v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect google.golang.org/grpc v1.77.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.34.2 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/client-go v0.34.2 // indirect - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + k8s.io/api v0.34.3 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/client-go v0.34.3 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/apps/shorturl/go.sum b/apps/shorturl/go.sum index 58ecc31fd82..36b5842b179 100644 --- a/apps/shorturl/go.sum +++ b/apps/shorturl/go.sum @@ -1,7 +1,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -25,14 +25,40 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= @@ -41,8 +67,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -56,10 +82,10 @@ github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGr github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4/go.mod h1:qeWYbnWzaYGl88JlL9+DsP1GT2Cudm58rLtx13fKZdw= 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/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250915132226-585b53bc7dba h1:Qam8QzVRsyZN39zgZ9Vj6e8PEfswvv2McnqCZ/v5NcI= github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250915132226-585b53bc7dba/go.mod h1:rlJ/mmE0RQolOB2+HV3+bw+ZifHyPDQurBwZEus+Wm0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= @@ -83,8 +109,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -116,10 +142,10 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -134,30 +160,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -175,34 +201,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -211,41 +237,41 @@ gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0 gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.1 h1:JrhdFMqOd/+3ByqlP2I45kTOZmTRLBUm5pvRjeheg7E= diff --git a/conf/defaults.ini b/conf/defaults.ini index a72b0183290..080d4e62fe0 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -335,6 +335,9 @@ rudderstack_data_plane_url = # Rudderstack SDK url, optional, only valid if rudderstack_write_key and rudderstack_data_plane_url is also set rudderstack_sdk_url = +# Rudderstack v3 SDK, optional, defaults to false. If set, Rudderstack v3 SDK will be used instead of v1 +rudderstack_v3_sdk_url = + # Rudderstack Config url, optional, used by Rudderstack SDK to fetch source config rudderstack_config_url = @@ -1327,6 +1330,10 @@ alertmanager_max_silences_count = # Maximum silence size in bytes. Default: 0 (no limit). alertmanager_max_silence_size_bytes = +# Maximum size of the expanded template output in bytes. Default: 10485760 (0 - no limit). +# The result of template expansion will be truncated to the limit. +alertmanager_max_template_output_bytes = + # Redis server address or addresses. It can be a single Redis address if using Redis standalone, # or a list of comma-separated addresses if using Redis Cluster/Sentinel. ha_redis_address = @@ -1646,6 +1653,11 @@ loki_basic_auth_password = # Accepts duration formats like: 30s, 1m, 1h. rule_query_offset = 1m +# Default data source UID to use for query execution when importing Prometheus rules. +# This default is used when the X-Grafana-Alerting-Datasource-UID header is not provided. +# If not set, the header becomes required. +default_datasource_uid = + [recording_rules] # Enable recording rules. enabled = true @@ -1747,9 +1759,8 @@ enabled = true #################################### Short Links ############################# [short_links] -# Short links that are never accessed will be deleted as cleanup. Time is set up in days. The default is 7 days. Maximum value is 365. -# 0 means they will be deleted approximately every 10 minutes. A negative value (such as -1) will disable expiration. -expire_time = 7 +# Short links that are never accessed will be deleted as cleanup. Time is set up in days. The default is -1 (never expire). Maximum value is 365. +expire_time = -1 #################################### Internal Grafana Metrics ############ # Metrics available at HTTP URL /metrics and /metrics/plugins/:pluginId @@ -2068,8 +2079,14 @@ enable = # To enable features by default, set `Expression: "true"` in: # https://github.com/grafana/grafana/blob/main/pkg/services/featuremgmt/registry.go +# The feature_toggles section supports feature flags of a number of types, +# including boolean, string, integer, float, and structured values, following the OpenFeature specification. +# # feature1 = true # feature2 = false +# feature3 = "foobar" +# feature4 = 1.5 +# feature5 = { "foo": "bar" } [feature_toggles.openfeature] # This is EXPERIMENTAL. Please, do not use this section @@ -2223,6 +2240,8 @@ encryption_provider = secret_key.v1 # These flags are required in on-prem installations for GitSync to work # +# Whether to register the MT CRUD API +register_api_server = true # Whether to create the MT secrets management database run_secrets_db_migrations = true # Whether to run the data key id migration. Requires that RunSecretsDBMigrations is also true. @@ -2258,7 +2277,7 @@ fail_tests_on_console = true # List of targets that can be controlled by a repository, separated by |. # Instance means the whole grafana instance will be controlled by a repository. # Folder limits it to a folder within the grafana instance. -allowed_targets = instance|folder +allowed_targets = folder # Whether image rendering is allowed for dashboard previews. # Requires image rendering service to be configured. @@ -2268,3 +2287,10 @@ allow_image_rendering = true # will check if there has been any changes to the repository not propagated by a webhook. # The minimum value is 10 seconds. min_sync_interval = 10s + +#################################### Unified Storage #################################### +[unified_storage] +# index_path is the path where unified storage can store its index files for search. +# If empty, defaults to "/unified-search/bleve" (see [paths] section). +# Please note that sharing the same index_path between multiple running Grafana instances is not supported. +index_path = diff --git a/conf/sample.ini b/conf/sample.ini index d6397f894e4..b4bc6027abf 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -322,6 +322,9 @@ # Rudderstack SDK url, optional, only valid if rudderstack_write_key and rudderstack_data_plane_url is also set ;rudderstack_sdk_url = +# Rudderstack v3 SDK, optional, defaults to false. If set, Rudderstack v3 SDK will be used instead of v1 +;rudderstack_v3_sdk_url = + # Rudderstack Config url, optional, used by Rudderstack SDK to fetch source config ;rudderstack_config_url = @@ -1612,6 +1615,11 @@ max_annotations_to_keep = # Accepts duration formats like: 30s, 1m, 1h. rule_query_offset = 1m +# Default data source UID to use for query execution when importing Prometheus rules. +# This default is used when the X-Grafana-Alerting-Datasource-UID header is not provided. +# If not set, the header becomes required. +default_datasource_uid = + #################################### Recording Rules ##################### [recording_rules] # Enable recording rules. @@ -1689,8 +1697,8 @@ default_datasource_uid = #################################### Short Links ############################# [short_links] -# Short links which are never accessed will be deleted as cleanup. Time is in days. Default is 7 days. Max is 365. 0 means they will be deleted approximately every 10 minutes. -;expire_time = 7 +# Short links that are never accessed will be deleted as cleanup. Time is set up in days. The default is -1 (never expire). Maximum value is 365. +;expire_time = -1 #################################### Internal Grafana Metrics ########################## # Metrics available at HTTP URL /metrics and /metrics/plugins/:pluginId @@ -1905,7 +1913,7 @@ default_datasource_uid = # client_queue_max_size is the maximum size in bytes of the client queue # for Live connections. Defaults to 4MB. -;client_queue_max_size = +;client_queue_max_size = #################################### Grafana Image Renderer Plugin ########################## [plugin.grafana-image-renderer] @@ -1988,9 +1996,14 @@ default_datasource_uid = ;enable = feature1,feature2 +# The feature_toggles section supports feature flags of a number of types, +# including boolean, string, integer, float, and structured values, following the OpenFeature specification. + ;feature1 = true ;feature2 = false - +;feature3 = "foobar" +;feature4 = 1.5 +;feature5 = { "foo": "bar" } [date_formats] # For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/ @@ -2115,6 +2128,8 @@ default_datasource_uid = # These flags are required in on-prem installations for GitSync to work # +# Whether to register the MT CRUD API +;register_api_server = true # Whether to create the MT secrets management database ;run_secrets_db_migrations = true # Whether to run the data key id migration. Requires that RunSecretsDBMigrations is also true. diff --git a/devenv/dev-dashboards/migrations/migrations.json b/devenv/dev-dashboards/migrations/migrations.json index 4c2160e1f26..ad063b99cf4 100644 --- a/devenv/dev-dashboards/migrations/migrations.json +++ b/devenv/dev-dashboards/migrations/migrations.json @@ -299,15 +299,9 @@ "y": 0 }, "id": 6, - "options": { - "code": { - "language": "plaintext", - "showLineNumbers": false, - "showMiniMap": false - }, - "content": "# Graph panel >> Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions", - "mode": "markdown" - }, + "options": {}, + "content": "# Graph panel >> Timeseries panel\n\nKnown issues:\n* hiding null/empty series\n* time regions", + "mode": "markdown", "pluginVersion": "11.0.0-pre", "targets": [ { diff --git a/devenv/dev-dashboards/panel-canvas/canvas_kitchen_sink.json b/devenv/dev-dashboards/panel-canvas/canvas_kitchen_sink.json new file mode 100644 index 00000000000..069a43c0888 --- /dev/null +++ b/devenv/dev-dashboards/panel-canvas/canvas_kitchen_sink.json @@ -0,0 +1,582 @@ +{ + "annotations": { + "list": [] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "-- Mixed --" + }, + "fieldConfig": { + "defaults": { + "mappings": [ + { + "options": { + "1": { + "color": "green", + "icon": "img/icons/unicons/check-circle.svg", + "index": 0, + "text": "Success" + }, + "2": { + "color": "orange", + "icon": "img/icons/unicons/exclamation-triangle.svg", + "index": 1, + "text": "Warning" + }, + "3": { + "color": "red", + "icon": "img/icons/unicons/times-circle.svg", + "index": 2, + "text": "Error" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "text", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "success" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "1": { + "color": "green", + "icon": "img/icons/unicons/check-circle.svg", + "index": 0, + "text": "Success" + } + }, + "type": "value" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "warning" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "2": { + "color": "orange", + "icon": "img/icons/unicons/exclamation-triangle.svg", + "index": 1, + "text": "Warning" + } + }, + "type": "value" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "error" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "3": { + "color": "red", + "icon": "img/icons/unicons/times-circle.svg", + "index": 2, + "text": "Error" + } + }, + "type": "value" + } + ] + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "unmapped" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "1": { + "color": "green", + "icon": "img/icons/unicons/check-circle.svg", + "index": 0, + "text": "Success" + }, + "2": { + "color": "orange", + "icon": "img/icons/unicons/exclamation-triangle.svg", + "index": 1, + "text": "Warning" + }, + "3": { + "color": "red", + "icon": "img/icons/unicons/times-circle.svg", + "index": 2, + "text": "Error" + } + }, + "type": "value" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "inlineEditing": true, + "root": { + "background": { + "color": { + "fixed": "transparent" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "elements": [ + { + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 16, + "text": { + "fixed": "Field-based Icons (from value mappings):", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Header", + "placement": { + "height": 40, + "left": 20, + "top": 10, + "width": 400 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "success", + "fixed": "green" + }, + "path": { + "field": "success", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Success Icon", + "placement": { + "height": 50, + "left": 50, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "success", + "fixed": "text" + }, + "size": 12, + "text": { + "field": "success", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Success Text", + "placement": { + "height": 25, + "left": 30, + "top": 115, + "width": 90 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "warning", + "fixed": "orange" + }, + "path": { + "field": "warning", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Warning Icon", + "placement": { + "height": 50, + "left": 180, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "warning", + "fixed": "text" + }, + "size": 12, + "text": { + "field": "warning", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Warning Text", + "placement": { + "height": 25, + "left": 160, + "top": 115, + "width": 90 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "error", + "fixed": "red" + }, + "path": { + "field": "error", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Error Icon", + "placement": { + "height": 50, + "left": 310, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "error", + "fixed": "text" + }, + "size": 12, + "text": { + "field": "error", + "mode": "field" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Error Text", + "placement": { + "height": 25, + "left": 290, + "top": 115, + "width": 90 + }, + "type": "text" + }, + { + "config": { + "fill": { + "field": "unmapped", + "fixed": "#808080" + }, + "path": { + "field": "unmapped", + "fixed": "img/icons/unicons/question-circle.svg", + "mode": "field" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Unmapped Icon", + "placement": { + "height": 50, + "left": 440, + "top": 60, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "field": "unmapped", + "fixed": "text" + }, + "size": 12, + "text": { + "fixed": "No mapping (14)", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Unmapped Text", + "placement": { + "height": 25, + "left": 410, + "top": 115, + "width": 110 + }, + "type": "text" + }, + { + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 14, + "text": { + "fixed": "Fixed Relative Path:", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Relative Label", + "placement": { + "height": 30, + "left": 50, + "top": 170, + "width": 200 + }, + "type": "text" + }, + { + "config": { + "fill": { + "fixed": "blue" + }, + "path": { + "fixed": "img/icons/unicons/cloud.svg", + "mode": "fixed" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Relative Icon", + "placement": { + "height": 50, + "left": 260, + "top": 165, + "width": 50 + }, + "type": "icon" + }, + { + "config": { + "align": "center", + "color": { + "fixed": "text" + }, + "size": 14, + "text": { + "fixed": "Fixed Absolute URL:", + "mode": "fixed" + }, + "valign": "middle" + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Absolute Label", + "placement": { + "height": 30, + "left": 50, + "top": 240, + "width": 200 + }, + "type": "text" + }, + { + "config": { + "fill": { + "fixed": "purple" + }, + "path": { + "fixed": "https://grafana.com/static/assets/img/grafana_icon.svg", + "mode": "fixed" + } + }, + "constraint": { + "horizontal": "left", + "vertical": "top" + }, + "name": "Absolute Icon", + "placement": { + "height": 50, + "left": 260, + "top": 235, + "width": 50 + }, + "type": "icon" + } + ], + "name": "Canvas Root", + "placement": { + "height": 100, + "left": 0, + "top": 0, + "width": 100 + }, + "type": "frame" + } + }, + "pluginVersion": "12.1.0", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content", + "csvContent": "success\n1" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "B", + "scenarioId": "csv_content", + "csvContent": "warning\n2" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "C", + "scenarioId": "csv_content", + "csvContent": "error\n3" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "D", + "scenarioId": "csv_content", + "csvContent": "unmapped\n14" + } + ], + "title": "Various SVG icons", + "type": "canvas" + } + ], + "schemaVersion": 39, + "tags": ["canvas", "icons", "test", "v2"], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Panel tests - Canvas - Kitchen sink", + "uid": "canvas-icon-fix-test-v2", + "version": 1, + "weekStart": "" +} diff --git a/devenv/dev-dashboards/panel-gauge/gauge_tests.json b/devenv/dev-dashboards/panel-gauge/gauge_tests.json index 0c8e2651e67..f32ace420b4 100644 --- a/devenv/dev-dashboards/panel-gauge/gauge_tests.json +++ b/devenv/dev-dashboards/panel-gauge/gauge_tests.json @@ -600,6 +600,20 @@ "stringInput": "null,null" } ], + "transformations": [ + { + "id": "convertFieldType", + "options": { + "fields": {}, + "conversions": [ + { + "targetField": "A-series", + "destinationType": "number" + } + ] + } + } + ], "title": "Only nulls and no user set min & max", "type": "gauge" }, diff --git a/devenv/dev-dashboards/panel-gauge/gauge_tests_new.json b/devenv/dev-dashboards/panel-gauge/gauge_tests_new.json index 9cb204da48a..ff69226fdf5 100644 --- a/devenv/dev-dashboards/panel-gauge/gauge_tests_new.json +++ b/devenv/dev-dashboards/panel-gauge/gauge_tests_new.json @@ -71,14 +71,13 @@ "id": 1, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": false, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -148,14 +147,13 @@ "id": 4, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": false, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -225,14 +223,13 @@ "id": 3, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -299,94 +296,16 @@ "x": 12, "y": 1 }, - "id": 5, - "maxDataPoints": 20, - "options": { - "barWidthFactor": 0.4, - "effects": { - "barGlow": true, - "centerGlow": true, - "rounded": true, - "spotlight": true - }, - "gradient": "none", - "orientation": "auto", - "reduceOptions": { - "calcs": ["lastNotNull"], - "fields": "", - "values": false - }, - "segmentCount": 1, - "segmentSpacing": 0.3, - "shape": "circle", - "showThresholdLabels": false, - "showThresholdMarkers": false, - "sparkline": false - }, - "pluginVersion": "13.0.0-pre", - "targets": [ - { - "alias": "1", - "datasource": { - "type": "grafana-testdata-datasource" - }, - "max": 100, - "min": 1, - "noise": 22, - "refId": "A", - "scenarioId": "random_walk", - "spread": 22, - "startValue": 1 - } - ], - "title": "Spotlight", - "type": "radialbar" - }, - { - "datasource": { - "type": "grafana-testdata-datasource" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "thresholds" - }, - "mappings": [], - "max": 100, - "min": 0, - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": 0 - }, - { - "color": "red", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 6, - "w": 4, - "x": 16, - "y": 1 - }, "id": 8, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -450,20 +369,19 @@ "gridPos": { "h": 6, "w": 4, - "x": 0, - "y": 7 + "x": 16, + "y": 1 }, "id": 22, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -527,20 +445,19 @@ "gridPos": { "h": 6, "w": 4, - "x": 4, - "y": 7 + "x": 20, + "y": 1 }, "id": 23, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": true, "centerGlow": true, - "rounded": false, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -579,7 +496,7 @@ "h": 1, "w": 24, "x": 0, - "y": 13 + "y": 7 }, "id": 17, "panels": [], @@ -616,21 +533,20 @@ }, "gridPos": { "h": 6, - "w": 5, + "w": 4, "x": 0, - "y": 14 + "y": 8 }, "id": 18, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.1, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -693,21 +609,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 5, - "y": 14 + "w": 4, + "x": 4, + "y": 8 }, "id": 19, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.32, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -770,21 +685,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 10, - "y": 14 + "w": 4, + "x": 8, + "y": 8 }, "id": 20, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.57, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -847,21 +761,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 15, - "y": 14 + "w": 4, + "x": 12, + "y": 8 }, "id": 21, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidthFactor": 0.8, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -900,7 +813,7 @@ "h": 1, "w": 24, "x": 0, - "y": 20 + "y": 14 }, "id": 24, "panels": [], @@ -941,21 +854,20 @@ }, "gridPos": { "h": 6, - "w": 6, + "w": 4, "x": 0, - "y": 21 + "y": 15 }, "id": 25, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1018,21 +930,20 @@ }, "gridPos": { "h": 6, - "w": 6, - "x": 6, - "y": 21 + "w": 4, + "x": 4, + "y": 15 }, "id": 26, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1095,21 +1006,20 @@ }, "gridPos": { "h": 6, - "w": 5, - "x": 12, - "y": 21 + "w": 4, + "x": 8, + "y": 15 }, "id": 29, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1171,22 +1081,21 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 6, - "x": 0, - "y": 27 + "h": 6, + "w": 4, + "x": 12, + "y": 15 }, "id": 30, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1248,22 +1157,21 @@ "overrides": [] }, "gridPos": { - "h": 7, - "w": 6, - "x": 6, - "y": 27 + "h": 6, + "w": 4, + "x": 16, + "y": 15 }, "id": 28, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.72, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false }, - "gradient": "none", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1298,7 +1206,7 @@ "h": 1, "w": 24, "x": 0, - "y": 34 + "y": 21 }, "id": 31, "panels": [], @@ -1345,19 +1253,18 @@ "h": 10, "w": 7, "x": 0, - "y": 35 + "y": 22 }, "id": 32, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1426,19 +1333,18 @@ "h": 10, "w": 7, "x": 7, - "y": 35 + "y": 22 }, "id": 34, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1507,19 +1413,18 @@ "h": 10, "w": 6, "x": 14, - "y": 35 + "y": 22 }, "id": 33, "maxDataPoints": 20, "options": { + "barShape": "flat", "barWidthFactor": 0.9, "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": true }, - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1554,7 +1459,7 @@ "h": 1, "w": 24, "x": 0, - "y": 45 + "y": 32 }, "id": 6, "panels": [], @@ -1565,7 +1470,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1596,21 +1500,21 @@ "h": 6, "w": 24, "x": 0, - "y": 46 + "y": 33 }, "id": 9, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, + "endpointMarker": "glow", "glow": "both", - "gradient": "auto", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1622,8 +1526,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1631,7 +1534,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 98, "min": 5, "noise": 22, @@ -1649,7 +1551,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1680,21 +1581,20 @@ "h": 6, "w": 24, "x": 0, - "y": 52 + "y": 39 }, "id": 11, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.4, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1706,8 +1606,7 @@ "shape": "gauge", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": true, - "spotlight": true + "sparkline": true }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1715,7 +1614,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 98, "min": 5, "noise": 22, @@ -1735,7 +1633,7 @@ "h": 1, "w": 24, "x": 0, - "y": 58 + "y": 45 }, "id": 12, "panels": [], @@ -1746,7 +1644,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1778,21 +1675,20 @@ "h": 7, "w": 4, "x": 0, - "y": 59 + "y": 46 }, "id": 13, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1804,8 +1700,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1813,7 +1708,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 8, "min": 1, "noise": 2, @@ -1824,6 +1718,22 @@ "startValue": 0 } ], + "transformations": [ + { + "id": "calculateField", + "options": { + "mode": "unary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true, + "unary": { + "operator": "round", + "fieldName": "A-series" + } + } + } + ], "title": "Active gateways", "type": "radialbar" }, @@ -1831,7 +1741,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1863,22 +1772,20 @@ "h": 7, "w": 5, "x": 4, - "y": 59 + "y": 46 }, "id": 14, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.49, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "sparkline": false, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "scheme", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1890,8 +1797,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1899,7 +1805,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 12, "min": 1, "noise": 2, @@ -1910,6 +1815,22 @@ "startValue": 0 } ], + "transformations": [ + { + "id": "calculateField", + "options": { + "mode": "unary", + "reduce": { + "reducer": "sum" + }, + "replaceFields": true, + "unary": { + "operator": "round", + "fieldName": "A-series" + } + } + } + ], "title": "Active pods", "type": "radialbar" }, @@ -1917,7 +1838,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -1948,21 +1868,20 @@ "h": 7, "w": 5, "x": 9, - "y": 59 + "y": 46 }, "id": 15, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.84, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -1974,8 +1893,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -1983,7 +1901,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 100, "min": 10, "noise": 22, @@ -2001,7 +1918,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "description": "", "fieldConfig": { "defaults": { "color": { @@ -2032,21 +1948,20 @@ "h": 7, "w": 6, "x": 14, - "y": 59 + "y": 46 }, "id": 16, "maxDataPoints": 20, "options": { + "barShape": "rounded", "barWidth": 12, "barWidthFactor": 0.66, "effects": { "barGlow": true, "centerGlow": true, - "rounded": true, - "spotlight": true + "gradient": true }, "glow": "both", - "gradient": "hue", "orientation": "auto", "reduceOptions": { "calcs": ["lastNotNull"], @@ -2058,8 +1973,7 @@ "shape": "circle", "showThresholdLabels": false, "showThresholdMarkers": false, - "sparkline": false, - "spotlight": true + "sparkline": false }, "pluginVersion": "13.0.0-pre", "targets": [ @@ -2067,7 +1981,6 @@ "datasource": { "type": "grafana-testdata-datasource" }, - "hide": false, "max": 100, "min": 10, "noise": 22, @@ -2080,6 +1993,145 @@ ], "title": "Backend", "type": "radialbar" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 53 + }, + "id": 35, + "panels": [], + "title": "Empty data", + "type": "row" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 12, + "x": 0, + "y": 54 + }, + "id": 36, + "options": { + "barShape": "flat", + "barWidthFactor": 0.5, + "effects": { + "barGlow": false, + "centerGlow": false, + "gradient": true + }, + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "segmentCount": 1, + "segmentSpacing": 0.3, + "shape": "gauge", + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sparkline": true + }, + "pluginVersion": "13.0.0-pre", + "targets": [ + { + "refId": "A", + "scenarioId": "random_walk", + "seriesCount": 0 + } + ], + "title": "Numeric, no series", + "type": "gauge" + }, + { + "datasource": { + "type": "grafana-testdata-datasource" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 12, + "x": 12, + "y": 54 + }, + "id": 37, + "options": { + "barShape": "flat", + "barWidthFactor": 0.5, + "effects": { + "barGlow": false, + "centerGlow": false, + "gradient": true + }, + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "segmentCount": 1, + "segmentSpacing": 0.3, + "shape": "gauge", + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sparkline": true + }, + "pluginVersion": "13.0.0-pre", + "targets": [ + { + "refId": "A", + "scenarioId": "logs" + } + ], + "title": "Non-numeric", + "type": "gauge" } ], "preload": false, @@ -2096,5 +2148,6 @@ "timezone": "browser", "title": "Panel tests - Gauge (new)", "uid": "panel-tests-gauge-new", - "version": 6 + "version": 22, + "weekStart": "" } diff --git a/devenv/dev-dashboards/panel-gauge/gauge_tests_old_to_new.json b/devenv/dev-dashboards/panel-gauge/gauge_tests_old_to_new.json index 61bec02a59b..3ca00ad5b63 100644 --- a/devenv/dev-dashboards/panel-gauge/gauge_tests_old_to_new.json +++ b/devenv/dev-dashboards/panel-gauge/gauge_tests_old_to_new.json @@ -474,6 +474,7 @@ }, "id": 12, "options": { + "displayName": "My gauge", "minVizHeight": 75, "minVizWidth": 75, "orientation": "auto", @@ -947,7 +948,6 @@ }, "orientation": "auto", "shape": "gauge", - "gradient": "none", "barWidthFactor": 0.5, "segmentCount": 70, "segmentSpacing": 0.3, @@ -957,8 +957,7 @@ "effects": { "barGlow": false, "centerGlow": false, - "rounded": false, - "spotlight": false + "gradient": false } } }, diff --git a/devenv/dev-dashboards/panel-piechart/panel_test_piechart.json b/devenv/dev-dashboards/panel-piechart/panel_test_piechart.json index 4333993ea8e..ac11fd803b9 100644 --- a/devenv/dev-dashboards/panel-piechart/panel_test_piechart.json +++ b/devenv/dev-dashboards/panel-piechart/panel_test_piechart.json @@ -248,7 +248,7 @@ "legend": { "values": ["percent"], "displayMode": "table", - "placement": "bottom" + "placement": "right" }, "pieType": "pie", "reduceOptions": { @@ -256,7 +256,7 @@ "fields": "", "values": false }, - "showLegend": false, + "showLegend": true, "strokeWidth": 1, "text": {} }, @@ -272,6 +272,15 @@ "timeFrom": null, "timeShift": null, "title": "Percent", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "^Backend-(.*)$", + "renamePattern": "b-$1" + } + } + ], "type": "piechart" }, { @@ -311,7 +320,7 @@ "legend": { "values": ["value"], "displayMode": "table", - "placement": "bottom" + "placement": "right" }, "pieType": "pie", "reduceOptions": { @@ -319,7 +328,7 @@ "fields": "", "values": false }, - "showLegend": false, + "showLegend": true, "strokeWidth": 1, "text": {} }, @@ -335,6 +344,15 @@ "timeFrom": null, "timeShift": null, "title": "Value", + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "(.*)", + "renamePattern": "$1-how-much-wood-could-a-woodchuck-chuck-if-a-woodchuck-could-chuck-wood" + } + } + ], "type": "piechart" }, { diff --git a/devenv/docker/blocks/mysql/docker-compose.yaml b/devenv/docker/blocks/mysql/docker-compose.yaml index cd5de0e6e67..c0c5403ef25 100644 --- a/devenv/docker/blocks/mysql/docker-compose.yaml +++ b/devenv/docker/blocks/mysql/docker-compose.yaml @@ -7,7 +7,15 @@ MYSQL_PASSWORD: password ports: - "3306:3306" - command: [mysqld, --character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci, --innodb_monitor_enable=all, --default-authentication-plugin=mysql_native_password] + command: + - mysqld + - --character-set-server=utf8mb4 + - --collation-server=utf8mb4_unicode_ci + - --innodb_monitor_enable=all + - --default-authentication-plugin=mysql_native_password + # Please keep sql-require-primary-key option enabled, to make sure we don't accidentally introduce migration + # adding new table without PK. + - --sql-require-primary-key=ON fake-mysql-data: image: grafana/fake-data-gen diff --git a/devenv/jsonnet/dev-dashboards.libsonnet b/devenv/jsonnet/dev-dashboards.libsonnet index cac117cd4e7..98eb14e9217 100644 --- a/devenv/jsonnet/dev-dashboards.libsonnet +++ b/devenv/jsonnet/dev-dashboards.libsonnet @@ -24,6 +24,7 @@ "canvas-connection-examples": (import '../dev-dashboards/panel-canvas/canvas-connection-examples.json'), "canvas-datalinks": (import '../dev-dashboards/panel-canvas/canvas-datalinks.json'), "canvas-examples": (import '../dev-dashboards/panel-canvas/canvas-examples.json'), + "canvas_kitchen_sink": (import '../dev-dashboards/panel-canvas/canvas_kitchen_sink.json'), "color_modes": (import '../dev-dashboards/panel-common/color_modes.json'), "config-from-query": (import '../dev-dashboards/transforms/config-from-query.json'), "dashlist": (import '../dev-dashboards/panel-dashlist/dashlist.json'), diff --git a/devenv/scopes/scopes-config.yaml b/devenv/scopes/scopes-config.yaml index 54842e5818e..66ba7b6988c 100644 --- a/devenv/scopes/scopes-config.yaml +++ b/devenv/scopes/scopes-config.yaml @@ -48,6 +48,23 @@ scopes: operator: equals value: kids + # This scope appears in multiple places in the tree. + # The defaultPath determines which path is shown when this scope is selected + # (e.g., from a URL or programmatically), even if another path also links to it. + shared-service: + title: Shared Service + # Path from the root node down to the direct scopeNode. + # Node names are hierarchical (parent-child), so use the full names. + # This points to: gdev-scopes > production > shared-service-prod + defaultPath: + - gdev-scopes + - gdev-scopes-production + - gdev-scopes-production-shared-service-prod + filters: + - key: service + operator: equals + value: shared + tree: gdev-scopes: title: gdev-scopes @@ -68,6 +85,13 @@ tree: nodeType: leaf linkId: app2 linkType: scope + # This node links to 'shared-service' scope. + # The scope's defaultPath points here (production > gdev-scopes). + shared-service-prod: + title: Shared Service + nodeType: leaf + linkId: shared-service + linkType: scope test-cases: title: Test cases nodeType: container @@ -83,6 +107,21 @@ tree: nodeType: leaf linkId: test-case-2 linkType: scope + # This node also links to the same 'shared-service' scope. + # However, the scope's defaultPath points to the production path, + # so selecting this scope will expand the tree to production > shared-service-prod. + shared-service-test: + title: Shared Service (also in Production) + subTitle: defaultPath points to Production + nodeType: leaf + linkId: shared-service + linkType: scope + test-case-redirect: + title: Test case with redirect + nodeType: leaf + linkId: shoe-org + linkType: scope + redirectPath: /d/dcb9f5e9-8066-4397-889e-864b99555dbb #Reliability dashboard clusters: title: Clusters nodeType: container @@ -119,6 +158,7 @@ navigationTree: url: /d/_5rDmaQiz scope: shoe-org subScope: shoes + preLoadSubScopeChildren: true children: - name: shoes-overview title: Overview @@ -135,6 +175,7 @@ navigationTree: url: /d/edediimbjhdz4b scope: shoes subScope: frontend + preLoadSubScopeChildren: true children: - name: frontend-api title: API Metrics @@ -204,6 +245,7 @@ navigationTree: url: /d/UTv--wqMk scope: shoe-org subScope: apparel + disableSubScopeSelection: true children: - name: apparel-product-overview title: Product Overview diff --git a/devenv/scopes/scopes.go b/devenv/scopes/scopes.go index 1f8a698ccda..4487c5b69ef 100644 --- a/devenv/scopes/scopes.go +++ b/devenv/scopes/scopes.go @@ -51,8 +51,9 @@ type Config struct { // ScopeConfig is used for YAML parsing - converts to v0alpha1.ScopeSpec type ScopeConfig struct { - Title string `yaml:"title"` - Filters []ScopeFilterConfig `yaml:"filters"` + Title string `yaml:"title"` + DefaultPath []string `yaml:"defaultPath,omitempty"` + Filters []ScopeFilterConfig `yaml:"filters"` } // ScopeFilterConfig is used for YAML parsing - converts to v0alpha1.ScopeFilter @@ -67,30 +68,36 @@ type ScopeFilterConfig struct { type TreeNode struct { Title string `yaml:"title"` SubTitle string `yaml:"subTitle,omitempty"` + Description string `yaml:"description,omitempty"` NodeType string `yaml:"nodeType"` LinkID string `yaml:"linkId,omitempty"` LinkType string `yaml:"linkType,omitempty"` DisableMultiSelect bool `yaml:"disableMultiSelect,omitempty"` + RedirectPath string `yaml:"redirectPath,omitempty"` Children map[string]TreeNode `yaml:"children,omitempty"` } type NavigationConfig struct { - URL string `yaml:"url"` // URL path (e.g., /d/abc123 or /explore) - Scope string `yaml:"scope"` // Required scope - SubScope string `yaml:"subScope"` // Optional subScope for hierarchical navigation - Title string `yaml:"title"` // Display title - Groups []string `yaml:"groups"` // Optional groups for categorization + URL string `yaml:"url"` // URL path (e.g., /d/abc123 or /explore) + Scope string `yaml:"scope"` // Required scope + SubScope string `yaml:"subScope"` // Optional subScope for hierarchical navigation + Title string `yaml:"title"` // Display title + Groups []string `yaml:"groups"` // Optional groups for categorization + DisableSubScopeSelection bool `yaml:"disableSubScopeSelection"` // Makes the subscope not selectable + PreLoadSubScopeChildren bool `yaml:"preLoadSubScopeChildren"` // Preload children of subScope without updating UI } // NavigationTreeNode represents a node in the navigation tree structure type NavigationTreeNode struct { - Name string `yaml:"name"` - Title string `yaml:"title"` - URL string `yaml:"url"` - Scope string `yaml:"scope"` - SubScope string `yaml:"subScope,omitempty"` - Groups []string `yaml:"groups,omitempty"` - Children []NavigationTreeNode `yaml:"children,omitempty"` + Name string `yaml:"name"` + Title string `yaml:"title"` + URL string `yaml:"url"` + Scope string `yaml:"scope"` + SubScope string `yaml:"subScope,omitempty"` + Groups []string `yaml:"groups,omitempty"` + DisableSubScopeSelection bool `yaml:"disableSubScopeSelection,omitempty"` + PreLoadSubScopeChildren bool `yaml:"preLoadSubScopeChildren,omitempty"` // Preload children of subScope without updating UI + Children []NavigationTreeNode `yaml:"children,omitempty"` } // Helper function to convert ScopeFilterConfig to v0alpha1.ScopeFilter @@ -110,9 +117,20 @@ func convertScopeSpec(cfg ScopeConfig) v0alpha1.ScopeSpec { for i, f := range cfg.Filters { filters[i] = convertFilter(f) } + + // Prefix defaultPath elements with the gdev prefix + var defaultPath []string + if len(cfg.DefaultPath) > 0 { + defaultPath = make([]string, len(cfg.DefaultPath)) + for i, p := range cfg.DefaultPath { + defaultPath[i] = prefix + "-" + p + } + } + return v0alpha1.ScopeSpec{ - Title: cfg.Title, - Filters: filters, + Title: cfg.Title, + DefaultPath: defaultPath, + Filters: filters, } } @@ -259,6 +277,7 @@ func (c *Client) createScopeNode(name string, node TreeNode, parentName string) spec := v0alpha1.ScopeNodeSpec{ Title: node.Title, SubTitle: node.SubTitle, + Description: node.Description, NodeType: nodeType, DisableMultiSelect: node.DisableMultiSelect, } @@ -272,6 +291,10 @@ func (c *Client) createScopeNode(name string, node TreeNode, parentName string) spec.LinkType = linkType } + if node.RedirectPath != "" { + spec.RedirectPath = node.RedirectPath + } + resource := v0alpha1.ScopeNode{ TypeMeta: metav1.TypeMeta{ APIVersion: apiVersion, @@ -306,8 +329,10 @@ func (c *Client) createScopeNavigation(name string, nav NavigationConfig) error prefixedScope := prefix + "-" + nav.Scope spec := v0alpha1.ScopeNavigationSpec{ - URL: nav.URL, - Scope: prefixedScope, + URL: nav.URL, + Scope: prefixedScope, + DisableSubScopeSelection: nav.DisableSubScopeSelection, + PreLoadSubScopeChildren: nav.PreLoadSubScopeChildren, } if nav.SubScope != "" { @@ -343,14 +368,14 @@ func (c *Client) createScopeNavigation(name string, nav NavigationConfig) error return err } + // Get the created resource to retrieve its resourceVersion for status update + createdNav, err := c.getScopeNavigation(prefixedName) + if err != nil { + return fmt.Errorf("failed to get created navigation: %w", err) + } + // Update status in a second request (status is a subresource) if nav.Title != "" || len(nav.Groups) > 0 { - // Get the created resource to retrieve its resourceVersion and existing spec - createdNav, err := c.getScopeNavigation(prefixedName) - if err != nil { - return fmt.Errorf("failed to get created navigation: %w", err) - } - statusResource := v0alpha1.ScopeNavigation{ TypeMeta: metav1.TypeMeta{ APIVersion: apiVersion, @@ -397,9 +422,11 @@ func treeToNavigations(node NavigationTreeNode, parentPath []string, dashboardCo // Create navigation for this node nav := NavigationConfig{ - URL: url, - Scope: node.Scope, - Title: node.Title, + URL: url, + Scope: node.Scope, + Title: node.Title, + DisableSubScopeSelection: node.DisableSubScopeSelection, + PreLoadSubScopeChildren: node.PreLoadSubScopeChildren, } if node.SubScope != "" { nav.SubScope = node.SubScope diff --git a/docs/Makefile b/docs/Makefile index 7bdbe026293..8202b11f826 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -7,8 +7,8 @@ MAKEFLAGS += --no-builtin-rule include docs.mk -.PHONY: sources/panels-visualizations/query-transform-data/transform-data/index.md -sources/panels-visualizations/query-transform-data/transform-data/index.md: ## Generate the Transform Data page source. +.PHONY: sources/visualizations/panels-visualizations/query-transform-data/transform-data/index.md +sources/visualizations/panels-visualizations/query-transform-data/transform-data/index.md: ## Generate the Transform Data page source. cd $(CURDIR)/.. && \ npx tsx ./scripts/docs/generate-transformations.ts && \ npx prettier -w $(CURDIR)/$@ diff --git a/docs/sources/administration/plugin-management/plugin-install.md b/docs/sources/administration/plugin-management/plugin-install.md index 18be4ea58fa..dfec5002944 100644 --- a/docs/sources/administration/plugin-management/plugin-install.md +++ b/docs/sources/administration/plugin-management/plugin-install.md @@ -21,11 +21,28 @@ weight: 120 # Install a plugin -Besides the UI, you can use alternative methods to install a plugin depending on your environment or set-up. +{{< admonition type="note" >}} + +Installing plugins from the Grafana website into a Grafana Cloud instance will be removed in February 2026. + +If you're a Grafana Cloud user, follow [Install a plugin through the Grafana UI](#install-a-plugin-through-the-grafana-uiinstall-a-plugin-through-the-grafana-ui) instead. + +{{< /admonition >}} + +## Install a plugin through the Grafana UI + +The most common way to install a plugin is through the Grafana UI. + +1. In Grafana, click **Administration > Plugins and data > Plugins** in the side navigation menu to view all plugins. +1. Browse and find a plugin. +1. Click the plugin's logo. +1. Click **Install**. + +You can use use the following alternative methods to install a plugin depending on your environment or setup. ## Install a plugin using Grafana CLI -The Grafana CLI allows you to install, upgrade, and manage your Grafana plugins using a command line tool. For more information about Grafana CLI plugin commands, refer to [Plugin commands](/docs/grafana//cli/#plugins-commands). +The Grafana CLI allows you to install, upgrade, and manage your Grafana plugins using a command line tool. For more information about Grafana CLI plugin commands, refer to [Plugin commands](https://grafana.com/docs/grafana//administration/cli/#plugins-commands). ## Install a plugin from a ZIP file diff --git a/docs/sources/administration/plugin-management/plugin-sign.md b/docs/sources/administration/plugin-management/plugin-sign.md index 7850996d0f6..54d65baacde 100644 --- a/docs/sources/administration/plugin-management/plugin-sign.md +++ b/docs/sources/administration/plugin-management/plugin-sign.md @@ -25,7 +25,7 @@ Plugin signature verification, also known as _signing_, is a security measure to Learn more at [plugin policies](https://grafana.com/legal/plugins/). -## How does verifiction work? +## How does verification work? At startup, Grafana verifies the signatures of every plugin in the plugin directory. diff --git a/docs/sources/administration/provisioning/index.md b/docs/sources/administration/provisioning/index.md index 15215275b53..29347497881 100644 --- a/docs/sources/administration/provisioning/index.md +++ b/docs/sources/administration/provisioning/index.md @@ -428,12 +428,25 @@ Or using a Kubernetes format, for example `kubernetes-dashboard.json`: You _must_ use the Kubernetes resource format to provision dashboards v2 / dynamic dashboards. -It later polls that path every `updateIntervalSeconds` for updates to the dashboard files and updates its database. - {{< admonition type="note" >}} Grafana installs dashboards at the root level if you don't set the `folder` field. {{< /admonition >}} +#### Detect updates to provisioned dashboards files + +After Grafana provisions your dashboards, it checks the filesystem for changes and updates dashboards as needed. + +The mechanism Grafana uses to do this depends on your `updateIntervalSeconds` value: + +- **More than 10 seconds**: Grafana polls the path at that interval. +- **10 seconds or less**: Grafana watches the filesystem for changes and updates dashboards when it detects them. + +{{< admonition type="note" >}} +When `updateIntervalSeconds` is 10 or less, Grafana relies on filesystem watch events to detect changes. +Depending on your filesystem and how you mount or sync dashboard files (for example, Docker bind mounts or some network filesystems), those events might not reach Grafana. +To work around this, set `updateIntervalSeconds` to more than 10 to force polling, or update your setup so filesystem watch events are propagated. +{{< /admonition >}} + #### Make changes to a provisioned dashboard You can make changes to a provisioned dashboard in the Grafana UI but its not possible to automatically save the changes back to the provisioning source. diff --git a/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md b/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md index 641d9bb4180..5fb3705232e 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/custom-role-actions-scopes/index.md @@ -238,6 +238,7 @@ For more information on Cloud Access Policies and how to use them, see [Access p | `alert.notifications.templates:read` | None | Read templates. | | `alert.notifications.templates:write` | None | Create new or update existing templates. | | `alert.notifications.templates:delete` | None | Delete existing templates. | +| `alert.notifications.templates.test:write` | None | Test templates with custom payloads (preview and payload editor functionality). | | `alert.notifications.routes:read` | None | Read notification policies. | | `alert.notifications.routes:write` | None | Create new, update or delete notification policies | diff --git a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md index 43b6e9c74a1..82ebfa0c49a 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md @@ -44,7 +44,7 @@ refs: destination: /docs/grafana-cloud/alerting-and-irm/oncall/user-and-team-management/#available-grafana-oncall-rbac-roles--granted-actions --- -# RBAC role definitions +# Grafana RBAC role definitions {{< admonition type="note" >}} Available in [Grafana Enterprise](/docs/grafana//introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). @@ -59,7 +59,7 @@ The following tables list permissions associated with basic and fixed roles. Thi | Grafana Admin | `basic_grafana_admin` | | `fixed:authentication.config:writer`
`fixed:general.auth.config:writer`
`fixed:ldap:writer`
`fixed:licensing:writer`
`fixed:migrationassistant:migrator`
`fixed:org.users:writer`
`fixed:organization:maintainer`
`fixed:plugins:maintainer`
`fixed:provisioning:writer`
`fixed:roles:writer`
`fixed:settings:reader`
`fixed:settings:writer`
`fixed:stats:reader`
`fixed:support.bundles:writer`
`fixed:usagestats:reader`
`fixed:users:writer` | Default [Grafana server administrator](/docs/grafana//administration/roles-and-permissions/#grafana-server-administrators) assignments. | | Admin | `basic_admin` | All roles assigned to Editor and `fixed:reports:writer`
`fixed:datasources:writer`
`fixed:organization:writer`
`fixed:datasources.permissions:writer`
`fixed:teams:writer`
`fixed:dashboards:writer`
`fixed:dashboards.permissions:writer`
`fixed:dashboards.public:writer`
`fixed:folders:writer`
`fixed:folders.permissions:writer`
`fixed:alerting:writer`
`fixed:alerting.provisioning.secrets:reader`
`fixed:alerting.provisioning:writer`
`fixed:datasources.caching:writer`
`fixed:plugins:writer`
`fixed:library.panels:writer` | Default [Grafana organization administrator](ref:rbac-basic-roles) assignments. | -| Editor | `basic_editor` | All roles assigned to Viewer and `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:alerting:writer`
`fixed:library.panels:creator`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer` | Default [Editor](ref:rbac-basic-roles) assignments. | +| Editor | `basic_editor` | All roles assigned to Viewer and `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:alerting:writer`
`fixed:library.panels:creator`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.provenance:writer` | Default [Editor](ref:rbac-basic-roles) assignments. | | Viewer | `basic_viewer` | `fixed:datasources.id:reader`
`fixed:organization:reader`
`fixed:annotations:reader`
`fixed:annotations.dashboard:writer`
`fixed:alerting:reader`
`fixed:plugins.app:reader`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:general.reader`
`fixed:folders.general:reader`
`fixed:datasources.builtin:reader` | Default [Viewer](ref:rbac-basic-roles) assignments. | | No Basic Role | n/a | | Default [No Basic Role](ref:rbac-basic-roles) | @@ -74,86 +74,86 @@ These UUIDs won't be available if your instance was created before Grafana v10.2 To learn how to use the roles API to determine the role UUIDs, refer to [Manage RBAC roles](ref:rbac-manage-rbac-roles). {{< /admonition >}} -| Fixed role | UUID | Permissions | Description | -| -------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `fixed:alerting:reader` | `fixed_O2oP1_uBFozI2i93klAkcvEWR30` | All permissions from `fixed:alerting.rules:reader`
`fixed:alerting.instances:reader`
`fixed:alerting.notifications:reader` | Read-only permissions for all Grafana, Mimir, Loki and Alertmanager alert rules\*, alerts, contact points, and notification policies.[\*](#alerting-roles) | -| `fixed:alerting:writer` | `fixed_-PAZgSJsDlRD8NUg-PFSeH_BkJY` | All permissions from `fixed:alerting.rules:writer`
`fixed:alerting.instances:writer`
`fixed:alerting.notifications:writer` | Create, update, and delete Grafana, Mimir, Loki and Alertmanager alert rules\*, silences, contact points, templates, mute timings, and notification policies.[\*](#alerting-roles) | -| `fixed:alerting.instances:reader` | `fixed_ut5fVS-Ulh_ejFoskFhJT_rYg0Y` | `alert.instances:read` for organization scope
`alert.instances.external:read` for scope `datasources:*` | Read all alerts and silences in the organization produced by Grafana Alerts and Mimir and Loki alerts and silences.[\*](#alerting-roles) | -| `fixed:alerting.instances:writer` | `fixed_pKOBJE346uyqMLdgWbk1NsQfEl0` | All permissions from `fixed:alerting.instances:reader` and
`alert.instances:create`
`alert.instances:write` for organization scope
`alert.instances.external:write` for scope `datasources:*` | Create, update and expire all silences in the organization produced by Grafana, Mimir, and Loki.[\*](#alerting-roles) | -| `fixed:alerting.notifications:reader` | `fixed_hmBn0lX5h1RZXB9Vaot420EEdA0` | `alert.notifications:read` for organization scope
`alert.notifications.external:read` for scope `datasources:*` | Read all Grafana and Alertmanager contact points, templates, and notification policies.[\*](#alerting-roles) | -| `fixed:alerting.notifications:writer` | `fixed_XplK6HPNxf9AP5IGTdB5Iun4tJc` | All permissions from `fixed:alerting.notifications:reader` and
`alert.notifications:write`for organization scope
`alert.notifications.external:read` for scope `datasources:*` | Create, update, and delete contact points, templates, mute timings and notification policies for Grafana and external Alertmanager.[\*](#alerting-roles) | -| `fixed:alerting.provisioning:writer` | `fixed_y7pFjdEkxpx5ETdcxPvp0AgRuUo` | `alert.provisioning:read` and `alert.provisioning:write` | Create, update and delete Grafana alert rules, notification policies, contact points, templates, etc via provisioning API. [\*](#alerting-roles) | -| `fixed:alerting.provisioning.secrets:reader` | `fixed_9fmzXXZZG-Od0Amy2ofEG8Uk--c` | `alert.provisioning:read` and `alert.provisioning.secrets:read` | Read-only permissions for Provisioning API and let export resources with decrypted secrets [\*](#alerting-roles) | -| `fixed:alerting.provisioning.status:writer` | `fixed_eAxlzfkTuobvKEgXHveFMBZrOj8` | `alert.provisioning.provenance:write` | Set provenance status to alert rules, notification policies, contact points, etc. Should be used together with regular writer roles. [\*](#alerting-roles) | -| `fixed:alerting.rules:reader` | `fixed_fRGKL_vAqUsmUWq5EYKnOha9DcA` | `alert.rule:read`, `alert.silences:read` for scope `folders:*`
`alert.rules.external:read` for scope `datasources:*`
`alert.notifications.time-intervals:read`
`alert.notifications.receivers:list` | Read all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) and read rule-specific silences | -| `fixed:alerting.rules:writer` | `fixed_YJJGwAalUwDZPrXSyFH8GfYBXAc` | All permissions from `fixed:alerting.rules:reader` and
`alert.rule:create`
`alert.rule:write`
`alert.rule:delete`
`alert.silences:create`
`alert.silences:write` for scope `folders:*`
`alert.rules.external:write` for scope `datasources:*` | Create, update, and delete all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) and manage rule-specific silences | -| `fixed:annotations:reader` | `fixed_hpZnoizrfAJsrceNcNQqWYV-xNU` | `annotations:read` for scopes `annotations:type:*` | Read all annotations and annotation tags. | -| `fixed:annotations:writer` | `fixed_ZVW-Aa9Tzle6J4s2aUFcq1StKWE` | All permissions from `fixed:annotations:reader`
`annotations:write`
`annotations.create`
`annotations:delete` for scope `annotations:type:*` | Read, create, update and delete all annotations and annotation tags. | -| `fixed:annotations.dashboard:writer` | `fixed_8A775xenXeKaJk4Cr7bchP9yXOA` | `annotations:write`
`annotations.create`
`annotations:delete` for scope `annotations:type:dashboard` | Create, update and delete dashboard annotations and annotation tags. | -| `fixed:authentication.config:writer` | `fixed_0rYhZ2Qnzs8AdB1nX7gexk3fHDw` | `settings:read` for scope `settings:auth.saml:*`
`settings:write` for scope `settings:auth.saml:*` | Read and update authentication and SAML settings. | -| `fixed:general.auth.config:writer` | `fixed_QFxIT_FGtBqbIVJIwx1bLgI5z6c` | `settings:read` for scope `settings:auth:oauth_allow_insecure_email_lookup`
`settings:write` for scope `settings:auth:oauth_allow_insecure_email_lookup` | Read and update the Grafana instance's general authentication configuration settings. | -| `fixed:dashboards:creator` | `fixed_ZorKUcEPCM01A1fPakEzGBUyU64` | `dashboards:create`
`folders:read` | Create dashboards. | -| `fixed:dashboards:reader` | `fixed_Sgr67JTOhjQGFlzYRahOe45TdWM` | `dashboards:read` | Read all dashboards. | -| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and
`dashboards:write`
`dashboards:delete`
`dashboards:create`
`dashboards.permissions:read`
`dashboards.permissions:write` | Read, create, update, and delete all dashboards. | -| `fixed:dashboards.insights:reader` | `fixed_JlBJ2_gizP8zhgaeGE2rjyZe2Rs` | `dashboards.insights:read` | Read dashboard insights data and see presence indicators. | -| `fixed:dashboards.permissions:reader` | `fixed_f17oxuXW_58LL8mYJsm4T_mCeIw` | `dashboards.permissions:read` | Read all dashboard permissions. | -| `fixed:dashboards.permissions:writer` | `fixed_CcznxhWX_Yqn8uWMXMQ-b5iFW9k` | All permissions from `fixed:dashboards.permissions:reader` and
`dashboards.permissions:write` | Read and update all dashboard permissions. | -| `fixed:dashboards.public:writer` | `fixed_f_GHHRBciaqESXfGz2oCcooqHxs` | `dashboards.public:write` | Create, update, delete or pause a shared dashboard. | -| `fixed:datasources:creator` | `fixed_XX8jHREgUt-wo1A-rPXIiFlX6Zw` | `datasources:create` | Create data sources. | -| `fixed:datasources:explorer` | `fixed_qDzW9mzx9yM91T5Bi8dHUM2muTw` | `datasources:explore` | Enable the Explore feature. Data source permissions still apply, you can only query data sources for which you have query permissions. | -| `fixed:datasources:reader` | `fixed_C2x8IxkiBc1KZVjyYH775T9jNMQ` | `datasources:read`
`datasources:query` | Read and query data sources. | -| `fixed:datasources:writer` | `fixed_q8HXq8kjjA5IlHHgBJlKlUyaNik` | All permissions from `fixed:datasources:reader` and
`datasources:create`
`datasources:write`
`datasources:delete` | Read, query, create, delete, or update a data source. | -| `fixed:datasources.builtin:reader` | `fixed_q8HXq8kjjA5IlHHgBJlKlUyaNik` | `datasources:read` and `datasources:query` scoped to `datasources:uid:grafana` | An internal role used to grant Viewers access to the builtin example data source in Grafana. | -| `fixed:datasources.caching:reader` | `fixed_D2ddpGxJYlw0mbsTS1ek9fj0kj4` | `datasources.caching:read` | Read data source query caching settings. | -| `fixed:datasources.caching:writer` | `fixed_JtFjHr7jd7hSqUYcktKvRvIOGRE` | `datasources.caching:read`
`datasources.caching:write` | Enable, disable, or update query caching settings. | -| `fixed:datasources.id:reader` | `fixed_entg--fHmDqWY2-69N0ocawK0Os` | `datasources.id:read` | Read the ID of a data source based on its name. | -| `fixed:datasources.insights:reader` | `fixed_EBZ3NwlfecNPp2p0XcZRC1nfEYk` | `datasources.insights:read` | Read data source insights data. | -| `fixed:datasources.permissions:reader` | `fixed_ErYA-cTN3yn4h4GxaVPcawRhiOY` | `datasources.permissions:read` | Read data source permissions. | -| `fixed:datasources.permissions:writer` | `fixed_aiQh9YDfLOKjQhYasF9_SFUjQiw` | All permissions from `fixed:datasources.permissions:reader` and
`datasources.permissions:write` | Create, read, or delete permissions of a data source. | -| `fixed:folders:creator` | `fixed_gGLRbZGAGB6n9uECqSh_W382RlQ` | `folders:create` | Create folders in the root level. | -| `fixed:folders:reader` | `fixed_yeW-5QPeo-i5PZUIUXMlAA97GnQ` | `folders:read`
`dashboards:read` | Read all folders and dashboards. | -| `fixed:folders:writer` | `fixed_wJXLoTzgE7jVuz90dryYoiogL0o` | All permissions from `fixed:dashboards:writer` and
`folders:read`
`folders:write`
`folders:create`
`folders:delete`
`folders.permissions:read`
`folders.permissions:write` | Read, update, and delete all folders and dashboards. Create folders and subfolders. | -| `fixed:folders.general:reader` | `fixed_rSASbkg8DvpG_gTX5s41d7uxRvI` | `folders:read` scoped to `folders:uid:general` | An internal role used to correctly display access to the folder tree for Viewer role. | -| `fixed:folders.permissions:reader` | `fixed_E06l4cx0JFm47EeLBE4nmv3pnSo` | `folders.permissions:read` | Read all folder permissions. | -| `fixed:folders.permissions:writer` | `fixed_3GAgpQ_hWG8o7-lwNb86_VB37eI` | All permissions from `fixed:folders.permissions:reader` and
`folders.permissions:write` | Read and update all folder permissions. | -| `fixed:ldap:reader` | `fixed_lMcOPwSkxKY-qCK8NMJc5k6izLE` | `ldap.user:read`
`ldap.status:read` | Read the LDAP configuration and LDAP status information. | -| `fixed:ldap:writer` | `fixed_p6AvnU4GCQyIh7-hbwI-bk3GYnU` | All permissions from `fixed:ldap:reader` and
`ldap.user:sync`
`ldap.config:reload` | Read and update the LDAP configuration, and read LDAP status information. | -| `fixed:library.panels:creator` | `fixed_6eX6ItfegCIY5zLmPqTDW8ZV7KY` | `library.panels:create`
`folders:read` | Create library panel at the root level. | -| `fixed:library.panels:general.reader` | `fixed_ct0DghiBWR_2BiQm3EvNPDVmpio` | `library.panels:read` | Read all library panels at the root level. | -| `fixed:library.panels:general.writer` | `fixed_DgprkmqfN_1EhZ2v1_d1fYG8LzI` | All permissions from `fixed:library.panels:general.reader` plus
`library.panels:create`
`library.panels:delete`
`library.panels:write` | Create, read, write or delete all library panels and their permissions at the root level. | -| `fixed:library.panels:reader` | `fixed_tvTr9CnZ6La5vvUO_U_X1LPnhUs` | `library.panels:read` | Read all library panels. | -| `fixed:library.panels:writer` | `fixed_JTljAr21LWLTXCkgfBC4H0lhBC8` | All permissions from `fixed:library.panels:reader` plus
`library.panels:create`
`library.panels:delete`
`library.panels:write` | Create, read, write or delete all library panels and their permissions. | -| `fixed:licensing:reader` | `fixed_OADpuXvNEylO2Kelu3GIuBXEAYE` | `licensing:read`
`licensing.reports:read` | Read licensing information and licensing reports. | -| `fixed:licensing:writer` | `fixed_gzbz3rJpQMdaKHt-E4q0PVaKMoE` | All permissions from `fixed:licensing:reader` and
`licensing:write`
`licensing:delete` | Read licensing information and licensing reports, update and delete the license token. | -| `fixed:migrationassistant:migrator` | `fixed_LLk2p7TRuBztOAksTQb1Klc8YTk` | `migrationassistant:migrate` | Execute on-prem to cloud migrations through the Migration Assistant. | -| `fixed:org.users:reader` | `fixed_oCqNwlVHLOpw7-jAlwp4HzYqwGY` | `org.users:read` | Read users within a single organization. | -| `fixed:org.users:writer` | `fixed_VERj5nayasjgf_Yh0sWqqCkxWlw` | All permissions from `fixed:org.users:reader` and
`org.users:add`
`org.users:remove`
`org.users:write` | Within a single organization, add a user, invite a new user, read information about a user and their role, remove a user from that organization, or change the role of a user. | -| `fixed:organization:maintainer` | `fixed_CMm-uuBaPUBf4r8XG3jIvxo55bg` | All permissions from `fixed:organization:reader` and
`orgs:write`
`orgs:create`
`orgs:delete`
`orgs.quotas:write` | Create, read, write, or delete an organization. Read or write its quotas. This role needs to be assigned globally. | -| `fixed:organization:reader` | `fixed_0SZPJlTHdNEe8zO91zv7Zwiwa2w` | `orgs:read`
`orgs.quotas:read` | Read an organization and its quotas. | -| `fixed:organization:writer` | `fixed_Y4jGqDd8w1yCrPwlik8z5Iu8-3M` | All permissions from `fixed:organization:reader` and
`orgs:write`
`orgs.preferences:read`
`orgs.preferences:write` | Read an organization, its quotas, or its preferences. Update organization properties, or its preferences. | -| `fixed:plugins:maintainer` | `fixed_yEOKidBcWgbm74x-nTa3lW5lOyY` | `plugins:install` | Install and uninstall plugins. Needs to be assigned globally. | -| `fixed:plugins:writer` | `fixed_MRYpGk7kpNNwt2VoVOXFiPnQziE` | `plugins:write` | Enable and disable plugins and edit plugins' settings. | -| `fixed:plugins.app:reader` | `fixed_AcZRiNYx7NueYkUqzw1o2OGGUAA` | `plugins.app:access` | Access application plugins (still enforcing the organization role). | -| `fixed:provisioning:writer` | `fixed_bgk1FCyR6OEDwhgirZlQgu5LlCA` | `provisioning:reload` | Reload provisioning. | -| `fixed:reports:reader` | `fixed_72_8LU_0ukfm6BdblOw8Z9q-GQ8` | `reports:read`
`reports:send`
`reports.settings:read` | Read all reports and shared report settings. | -| `fixed:reports:writer` | `fixed_jBW3_7g1EWOjGVBYeVRwtFxhUNw` | All permissions from `fixed:reports:reader` and
`reports:create`
`reports:write`
`reports:delete`
`reports.settings:write` | Create, read, update, or delete all reports and shared report settings. | -| `fixed:roles:reader` | `fixed_GkfG-1NSwEGb4hpK3-E3qHyNltc` | `roles:read`
`teams.roles:read`
`users.roles:read`
`users.permissions:read` | Read all access control roles, roles and permissions assigned to users, teams. | -| `fixed:roles:resetter` | `fixed_WgPpC3qJRmVpVTJavFNwfS5RuzQ` | `roles:write` with scope `permissions:type:escalate` | Reset basic roles to their default. | -| `fixed:roles:writer` | `fixed_W5aFaw8isAM27x_eWfElBhZ0iOc` | All permissions from `fixed:roles:reader` and
`roles:write`
`roles:delete`
`teams.roles:add`
`teams.roles:remove`
`users.roles:add`
`users.roles:remove` | Create, read, update, or delete all roles, assign or unassign roles to users, teams. | -| `fixed:serviceaccounts:creator` | `fixed_Ikw60fckA0MyiiZ73BawSfOULy4` | `serviceaccounts:create` | Create Grafana service accounts. | -| `fixed:serviceaccounts:reader` | `fixed_QFjJAZ88iawMLInYOxPA1DB1w6I` | `serviceaccounts:read` | Read Grafana service accounts. | -| `fixed:serviceaccounts:writer` | `fixed_iBvUNUEZBZ7PUW0vdkN5iojc2sk` | `serviceaccounts:read`
`serviceaccounts:create`
`serviceaccounts:write`
`serviceaccounts:delete`
`serviceaccounts.permissions:read`
`serviceaccounts.permissions:write` | Create, update, read and delete all Grafana service accounts and manage service account permissions. | -| `fixed:settings:reader` | `fixed_0LaUt1x6PP8hsZzEBhqPQZFUd8Q` | `settings:read` | Read Grafana instance settings. | -| `fixed:settings:writer` | `fixed_joIHDgMrGg790hMhUufVzcU4j44` | All permissions from `fixed:settings:reader` and
`settings:write` | Read and update Grafana instance settings. | -| `fixed:stats:reader` | `fixed_OnRCXxZVINWpcKvTF5A1gecJ7pA` | `server.stats:read` | Read Grafana instance statistics. | -| `fixed:support.bundles:reader` | `fixed_gcPjI3PTUJwRx-GJZwDhNa7zbos` | `support.bundles:read` | List and download support bundles. | -| `fixed:support.bundles:writer` | `fixed_dTgCv9Wxrp_WHAhwHYIgeboxKpE` | `support.bundles:read`
`support.bundles:create`
`support.bundles:delete` | Create, delete, list and download support bundles. | -| `fixed:teams:creator` | `fixed_nzVQoNSDSn0fg1MDgO6XnZX2RZI` | `teams:create`
`org.users:read` | Create a team and list organization users (required to manage the created team). | -| `fixed:teams:read` | `fixed_Z8pB0GQlrqRt8IZBCJQxPWvJPgQ` | `teams:read` | List all teams. | -| `fixed:teams:writer` | `fixed_xw1T0579h620MOYi4L96GUs7fZY` | `teams:create`
`teams:delete`
`teams:read`
`teams:write`
`teams.permissions:read`
`teams.permissions:write` | Create, read, update and delete teams and manage team memberships. | -| `fixed:usagestats:reader` | `fixed_eAM0azEvnWFCJAjNkUKnGL_1-bU` | `server.usagestats.report:read` | View usage statistics report. | -| `fixed:users:reader` | `fixed_buZastUG3reWyQpPemcWjGqPAd0` | `users:read`
`users.quotas:read`
`users.authtoken:read` | Read all users and their information, such as team memberships, authentication tokens, and quotas. | -| `fixed:users:writer` | `fixed_wjzgHHo_Ux25DJuELn_oiAdB_yM` | All permissions from `fixed:users:reader` and
`users:write`
`users:create`
`users:delete`
`users:enable`
`users:disable`
`users.password:write`
`users.permissions:write`
`users:logout`
`users.authtoken:write`
`users.quotas:write` | Read and update all attributes and settings for all users in Grafana: update user information, read user information, create or enable or disable a user, make a user a Grafana administrator, sign out a user, update a user’s authentication token, or update quotas for all users. | +| Fixed role | UUID | Permissions | Description | +| ----------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `fixed:alerting:reader` | `fixed_O2oP1_uBFozI2i93klAkcvEWR30` | All permissions from `fixed:alerting.rules:reader`
`fixed:alerting.instances:reader`
`fixed:alerting.notifications:reader` | Read-only permissions for all Grafana, Mimir, Loki and Alertmanager alert rules\*, alerts, contact points, and notification policies.[\*](#alerting-roles) | +| `fixed:alerting:writer` | `fixed_-PAZgSJsDlRD8NUg-PFSeH_BkJY` | All permissions from `fixed:alerting.rules:writer`
`fixed:alerting.instances:writer`
`fixed:alerting.notifications:writer` | Create, update, and delete Grafana, Mimir, Loki and Alertmanager alert rules\*, silences, contact points, templates, mute timings, and notification policies.[\*](#alerting-roles) | +| `fixed:alerting.instances:reader` | `fixed_ut5fVS-Ulh_ejFoskFhJT_rYg0Y` | `alert.instances:read` for organization scope
`alert.instances.external:read` for scope `datasources:*` | Read all alerts and silences in the organization produced by Grafana Alerts and Mimir and Loki alerts and silences.[\*](#alerting-roles) | +| `fixed:alerting.instances:writer` | `fixed_pKOBJE346uyqMLdgWbk1NsQfEl0` | All permissions from `fixed:alerting.instances:reader` and
`alert.instances:create`
`alert.instances:write` for organization scope
`alert.instances.external:write` for scope `datasources:*` | Create, update and expire all silences in the organization produced by Grafana, Mimir, and Loki.[\*](#alerting-roles) | +| `fixed:alerting.notifications:reader` | `fixed_hmBn0lX5h1RZXB9Vaot420EEdA0` | `alert.notifications:read` for organization scope
`alert.notifications.external:read` for scope `datasources:*` | Read all Grafana and Alertmanager contact points, templates, and notification policies.[\*](#alerting-roles) | +| `fixed:alerting.notifications:writer` | `fixed_XplK6HPNxf9AP5IGTdB5Iun4tJc` | All permissions from `fixed:alerting.notifications:reader` and
`alert.notifications:write`for organization scope
`alert.notifications.external:read` for scope `datasources:*` | Create, update, and delete contact points, templates, mute timings and notification policies for Grafana and external Alertmanager.[\*](#alerting-roles) | +| `fixed:alerting.provisioning:writer` | `fixed_y7pFjdEkxpx5ETdcxPvp0AgRuUo` | `alert.provisioning:read` and `alert.provisioning:write` | Create, update and delete Grafana alert rules, notification policies, contact points, templates, etc via provisioning API. [\*](#alerting-roles) | +| `fixed:alerting.provisioning.secrets:reader` | `fixed_9fmzXXZZG-Od0Amy2ofEG8Uk--c` | `alert.provisioning:read` and `alert.provisioning.secrets:read` | Read-only permissions for Provisioning API and let export resources with decrypted secrets [\*](#alerting-roles) | +| `fixed:alerting.provisioning.provenance:writer` | `fixed_eAxlzfkTuobvKEgXHveFMBZrOj8` | `alert.provisioning.provenance:write` | Set provenance status to alert rules, notification policies, contact points, etc. Should be used together with regular writer roles. [\*](#alerting-roles) | +| `fixed:alerting.rules:reader` | `fixed_fRGKL_vAqUsmUWq5EYKnOha9DcA` | `alert.rule:read`, `alert.silences:read` for scope `folders:*`
`alert.rules.external:read` for scope `datasources:*`
`alert.notifications.time-intervals:read`
`alert.notifications.receivers:list` | Read all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) and read rule-specific silences | +| `fixed:alerting.rules:writer` | `fixed_YJJGwAalUwDZPrXSyFH8GfYBXAc` | All permissions from `fixed:alerting.rules:reader` and
`alert.rule:create`
`alert.rule:write`
`alert.rule:delete`
`alert.silences:create`
`alert.silences:write` for scope `folders:*`
`alert.rules.external:write` for scope `datasources:*` | Create, update, and delete all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) and manage rule-specific silences | +| `fixed:annotations:reader` | `fixed_hpZnoizrfAJsrceNcNQqWYV-xNU` | `annotations:read` for scopes `annotations:type:*` | Read all annotations and annotation tags. | +| `fixed:annotations:writer` | `fixed_ZVW-Aa9Tzle6J4s2aUFcq1StKWE` | All permissions from `fixed:annotations:reader`
`annotations:write`
`annotations.create`
`annotations:delete` for scope `annotations:type:*` | Read, create, update and delete all annotations and annotation tags. | +| `fixed:annotations.dashboard:writer` | `fixed_8A775xenXeKaJk4Cr7bchP9yXOA` | `annotations:write`
`annotations.create`
`annotations:delete` for scope `annotations:type:dashboard` | Create, update and delete dashboard annotations and annotation tags. | +| `fixed:authentication.config:writer` | `fixed_0rYhZ2Qnzs8AdB1nX7gexk3fHDw` | `settings:read` for scope `settings:auth.saml:*`
`settings:write` for scope `settings:auth.saml:*` | Read and update authentication and SAML settings. | +| `fixed:general.auth.config:writer` | `fixed_QFxIT_FGtBqbIVJIwx1bLgI5z6c` | `settings:read` for scope `settings:auth:oauth_allow_insecure_email_lookup`
`settings:write` for scope `settings:auth:oauth_allow_insecure_email_lookup` | Read and update the Grafana instance's general authentication configuration settings. | +| `fixed:dashboards:creator` | `fixed_ZorKUcEPCM01A1fPakEzGBUyU64` | `dashboards:create`
`folders:read` | Create dashboards. | +| `fixed:dashboards:reader` | `fixed_Sgr67JTOhjQGFlzYRahOe45TdWM` | `dashboards:read` | Read all dashboards. | +| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and
`dashboards:write`
`dashboards:delete`
`dashboards:create`
`dashboards.permissions:read`
`dashboards.permissions:write` | Read, create, update, and delete all dashboards. | +| `fixed:dashboards.insights:reader` | `fixed_JlBJ2_gizP8zhgaeGE2rjyZe2Rs` | `dashboards.insights:read` | Read dashboard insights data and see presence indicators. | +| `fixed:dashboards.permissions:reader` | `fixed_f17oxuXW_58LL8mYJsm4T_mCeIw` | `dashboards.permissions:read` | Read all dashboard permissions. | +| `fixed:dashboards.permissions:writer` | `fixed_CcznxhWX_Yqn8uWMXMQ-b5iFW9k` | All permissions from `fixed:dashboards.permissions:reader` and
`dashboards.permissions:write` | Read and update all dashboard permissions. | +| `fixed:dashboards.public:writer` | `fixed_f_GHHRBciaqESXfGz2oCcooqHxs` | `dashboards.public:write` | Create, update, delete or pause a shared dashboard. | +| `fixed:datasources:creator` | `fixed_XX8jHREgUt-wo1A-rPXIiFlX6Zw` | `datasources:create` | Create data sources. | +| `fixed:datasources:explorer` | `fixed_qDzW9mzx9yM91T5Bi8dHUM2muTw` | `datasources:explore` | Enable the Explore feature. Data source permissions still apply, you can only query data sources for which you have query permissions. | +| `fixed:datasources:reader` | `fixed_C2x8IxkiBc1KZVjyYH775T9jNMQ` | `datasources:read`
`datasources:query` | Read and query data sources. | +| `fixed:datasources:writer` | `fixed_q8HXq8kjjA5IlHHgBJlKlUyaNik` | All permissions from `fixed:datasources:reader` and
`datasources:create`
`datasources:write`
`datasources:delete` | Read, query, create, delete, or update a data source. | +| `fixed:datasources.builtin:reader` | `fixed_q8HXq8kjjA5IlHHgBJlKlUyaNik` | `datasources:read` and `datasources:query` scoped to `datasources:uid:grafana` | An internal role used to grant Viewers access to the builtin example data source in Grafana. | +| `fixed:datasources.caching:reader` | `fixed_D2ddpGxJYlw0mbsTS1ek9fj0kj4` | `datasources.caching:read` | Read data source query caching settings. | +| `fixed:datasources.caching:writer` | `fixed_JtFjHr7jd7hSqUYcktKvRvIOGRE` | `datasources.caching:read`
`datasources.caching:write` | Enable, disable, or update query caching settings. | +| `fixed:datasources.id:reader` | `fixed_entg--fHmDqWY2-69N0ocawK0Os` | `datasources.id:read` | Read the ID of a data source based on its name. | +| `fixed:datasources.insights:reader` | `fixed_EBZ3NwlfecNPp2p0XcZRC1nfEYk` | `datasources.insights:read` | Read data source insights data. | +| `fixed:datasources.permissions:reader` | `fixed_ErYA-cTN3yn4h4GxaVPcawRhiOY` | `datasources.permissions:read` | Read data source permissions. | +| `fixed:datasources.permissions:writer` | `fixed_aiQh9YDfLOKjQhYasF9_SFUjQiw` | All permissions from `fixed:datasources.permissions:reader` and
`datasources.permissions:write` | Create, read, or delete permissions of a data source. | +| `fixed:folders:creator` | `fixed_gGLRbZGAGB6n9uECqSh_W382RlQ` | `folders:create` | Create folders in the root level. | +| `fixed:folders:reader` | `fixed_yeW-5QPeo-i5PZUIUXMlAA97GnQ` | `folders:read`
`dashboards:read` | Read all folders and dashboards. | +| `fixed:folders:writer` | `fixed_wJXLoTzgE7jVuz90dryYoiogL0o` | All permissions from `fixed:dashboards:writer` and
`folders:read`
`folders:write`
`folders:create`
`folders:delete`
`folders.permissions:read`
`folders.permissions:write` | Read, update, and delete all folders and dashboards. Create folders and subfolders. | +| `fixed:folders.general:reader` | `fixed_rSASbkg8DvpG_gTX5s41d7uxRvI` | `folders:read` scoped to `folders:uid:general` | An internal role used to correctly display access to the folder tree for Viewer role. | +| `fixed:folders.permissions:reader` | `fixed_E06l4cx0JFm47EeLBE4nmv3pnSo` | `folders.permissions:read` | Read all folder permissions. | +| `fixed:folders.permissions:writer` | `fixed_3GAgpQ_hWG8o7-lwNb86_VB37eI` | All permissions from `fixed:folders.permissions:reader` and
`folders.permissions:write` | Read and update all folder permissions. | +| `fixed:ldap:reader` | `fixed_lMcOPwSkxKY-qCK8NMJc5k6izLE` | `ldap.user:read`
`ldap.status:read` | Read the LDAP configuration and LDAP status information. | +| `fixed:ldap:writer` | `fixed_p6AvnU4GCQyIh7-hbwI-bk3GYnU` | All permissions from `fixed:ldap:reader` and
`ldap.user:sync`
`ldap.config:reload` | Read and update the LDAP configuration, and read LDAP status information. | +| `fixed:library.panels:creator` | `fixed_6eX6ItfegCIY5zLmPqTDW8ZV7KY` | `library.panels:create`
`folders:read` | Create library panel at the root level. | +| `fixed:library.panels:general.reader` | `fixed_ct0DghiBWR_2BiQm3EvNPDVmpio` | `library.panels:read` | Read all library panels at the root level. | +| `fixed:library.panels:general.writer` | `fixed_DgprkmqfN_1EhZ2v1_d1fYG8LzI` | All permissions from `fixed:library.panels:general.reader` plus
`library.panels:create`
`library.panels:delete`
`library.panels:write` | Create, read, write or delete all library panels and their permissions at the root level. | +| `fixed:library.panels:reader` | `fixed_tvTr9CnZ6La5vvUO_U_X1LPnhUs` | `library.panels:read` | Read all library panels. | +| `fixed:library.panels:writer` | `fixed_JTljAr21LWLTXCkgfBC4H0lhBC8` | All permissions from `fixed:library.panels:reader` plus
`library.panels:create`
`library.panels:delete`
`library.panels:write` | Create, read, write or delete all library panels and their permissions. | +| `fixed:licensing:reader` | `fixed_OADpuXvNEylO2Kelu3GIuBXEAYE` | `licensing:read`
`licensing.reports:read` | Read licensing information and licensing reports. | +| `fixed:licensing:writer` | `fixed_gzbz3rJpQMdaKHt-E4q0PVaKMoE` | All permissions from `fixed:licensing:reader` and
`licensing:write`
`licensing:delete` | Read licensing information and licensing reports, update and delete the license token. | +| `fixed:migrationassistant:migrator` | `fixed_LLk2p7TRuBztOAksTQb1Klc8YTk` | `migrationassistant:migrate` | Execute on-prem to cloud migrations through the Migration Assistant. | +| `fixed:org.users:reader` | `fixed_oCqNwlVHLOpw7-jAlwp4HzYqwGY` | `org.users:read` | Read users within a single organization. | +| `fixed:org.users:writer` | `fixed_VERj5nayasjgf_Yh0sWqqCkxWlw` | All permissions from `fixed:org.users:reader` and
`org.users:add`
`org.users:remove`
`org.users:write` | Within a single organization, add a user, invite a new user, read information about a user and their role, remove a user from that organization, or change the role of a user. | +| `fixed:organization:maintainer` | `fixed_CMm-uuBaPUBf4r8XG3jIvxo55bg` | All permissions from `fixed:organization:reader` and
`orgs:write`
`orgs:create`
`orgs:delete`
`orgs.quotas:write` | Create, read, write, or delete an organization. Read or write its quotas. This role needs to be assigned globally. | +| `fixed:organization:reader` | `fixed_0SZPJlTHdNEe8zO91zv7Zwiwa2w` | `orgs:read`
`orgs.quotas:read` | Read an organization and its quotas. | +| `fixed:organization:writer` | `fixed_Y4jGqDd8w1yCrPwlik8z5Iu8-3M` | All permissions from `fixed:organization:reader` and
`orgs:write`
`orgs.preferences:read`
`orgs.preferences:write` | Read an organization, its quotas, or its preferences. Update organization properties, or its preferences. | +| `fixed:plugins:maintainer` | `fixed_yEOKidBcWgbm74x-nTa3lW5lOyY` | `plugins:install` | Install and uninstall plugins. Needs to be assigned globally. | +| `fixed:plugins:writer` | `fixed_MRYpGk7kpNNwt2VoVOXFiPnQziE` | `plugins:write` | Enable and disable plugins and edit plugins' settings. | +| `fixed:plugins.app:reader` | `fixed_AcZRiNYx7NueYkUqzw1o2OGGUAA` | `plugins.app:access` | Access application plugins (still enforcing the organization role). | +| `fixed:provisioning:writer` | `fixed_bgk1FCyR6OEDwhgirZlQgu5LlCA` | `provisioning:reload` | Reload provisioning. | +| `fixed:reports:reader` | `fixed_72_8LU_0ukfm6BdblOw8Z9q-GQ8` | `reports:read`
`reports:send`
`reports.settings:read` | Read all reports and shared report settings. | +| `fixed:reports:writer` | `fixed_jBW3_7g1EWOjGVBYeVRwtFxhUNw` | All permissions from `fixed:reports:reader` and
`reports:create`
`reports:write`
`reports:delete`
`reports.settings:write` | Create, read, update, or delete all reports and shared report settings. | +| `fixed:roles:reader` | `fixed_GkfG-1NSwEGb4hpK3-E3qHyNltc` | `roles:read`
`teams.roles:read`
`users.roles:read`
`users.permissions:read` | Read all access control roles, roles and permissions assigned to users, teams. | +| `fixed:roles:resetter` | `fixed_WgPpC3qJRmVpVTJavFNwfS5RuzQ` | `roles:write` with scope `permissions:type:escalate` | Reset basic roles to their default. | +| `fixed:roles:writer` | `fixed_W5aFaw8isAM27x_eWfElBhZ0iOc` | All permissions from `fixed:roles:reader` and
`roles:write`
`roles:delete`
`teams.roles:add`
`teams.roles:remove`
`users.roles:add`
`users.roles:remove` | Create, read, update, or delete all roles, assign or unassign roles to users, teams. | +| `fixed:serviceaccounts:creator` | `fixed_Ikw60fckA0MyiiZ73BawSfOULy4` | `serviceaccounts:create` | Create Grafana service accounts. | +| `fixed:serviceaccounts:reader` | `fixed_QFjJAZ88iawMLInYOxPA1DB1w6I` | `serviceaccounts:read` | Read Grafana service accounts. | +| `fixed:serviceaccounts:writer` | `fixed_iBvUNUEZBZ7PUW0vdkN5iojc2sk` | `serviceaccounts:read`
`serviceaccounts:create`
`serviceaccounts:write`
`serviceaccounts:delete`
`serviceaccounts.permissions:read`
`serviceaccounts.permissions:write` | Create, update, read and delete all Grafana service accounts and manage service account permissions. | +| `fixed:settings:reader` | `fixed_0LaUt1x6PP8hsZzEBhqPQZFUd8Q` | `settings:read` | Read Grafana instance settings. | +| `fixed:settings:writer` | `fixed_joIHDgMrGg790hMhUufVzcU4j44` | All permissions from `fixed:settings:reader` and
`settings:write` | Read and update Grafana instance settings. | +| `fixed:stats:reader` | `fixed_OnRCXxZVINWpcKvTF5A1gecJ7pA` | `server.stats:read` | Read Grafana instance statistics. | +| `fixed:support.bundles:reader` | `fixed_gcPjI3PTUJwRx-GJZwDhNa7zbos` | `support.bundles:read` | List and download support bundles. | +| `fixed:support.bundles:writer` | `fixed_dTgCv9Wxrp_WHAhwHYIgeboxKpE` | `support.bundles:read`
`support.bundles:create`
`support.bundles:delete` | Create, delete, list and download support bundles. | +| `fixed:teams:creator` | `fixed_nzVQoNSDSn0fg1MDgO6XnZX2RZI` | `teams:create`
`org.users:read` | Create a team and list organization users (required to manage the created team). | +| `fixed:teams:read` | `fixed_Z8pB0GQlrqRt8IZBCJQxPWvJPgQ` | `teams:read` | List all teams. | +| `fixed:teams:writer` | `fixed_xw1T0579h620MOYi4L96GUs7fZY` | `teams:create`
`teams:delete`
`teams:read`
`teams:write`
`teams.permissions:read`
`teams.permissions:write` | Create, read, update and delete teams and manage team memberships. | +| `fixed:usagestats:reader` | `fixed_eAM0azEvnWFCJAjNkUKnGL_1-bU` | `server.usagestats.report:read` | View usage statistics report. | +| `fixed:users:reader` | `fixed_buZastUG3reWyQpPemcWjGqPAd0` | `users:read`
`users.quotas:read`
`users.authtoken:read` | Read all users and their information, such as team memberships, authentication tokens, and quotas. | +| `fixed:users:writer` | `fixed_wjzgHHo_Ux25DJuELn_oiAdB_yM` | All permissions from `fixed:users:reader` and
`users:write`
`users:create`
`users:delete`
`users:enable`
`users:disable`
`users.password:write`
`users.permissions:write`
`users:logout`
`users.authtoken:write`
`users.quotas:write` | Read and update all attributes and settings for all users in Grafana: update user information, read user information, create or enable or disable a user, make a user a Grafana administrator, sign out a user, update a user’s authentication token, or update quotas for all users. | ### Alerting roles @@ -164,10 +164,20 @@ Access to Grafana alert rules is an intersection of many permissions: - Permission to read a folder. For example, the fixed role `fixed:folders:reader` includes the action `folders:read` and a folder scope `folders:id:`. - Permission to query **all** data sources that a given alert rule uses. If a user cannot query a given data source, they cannot see any alert rules that query that data source. -There is only one exclusion at this moment. Role `fixed:alerting.provisioning:writer` does not require user to have any additional permissions and provides access to all aspects of the alerting configuration via special provisioning API. +There is only one exclusion. Role `fixed:alerting.provisioning:writer` does not require user to have any additional permissions and provides access to all aspects of the alerting configuration via special provisioning API. For more information about the permissions required to access alert rules, refer to [Create a custom role to access alerts in a folder](ref:plan-rbac-rollout-strategy-create-a-custom-role-to-access-alerts-in-a-folder). +#### Alerting basic roles + +The following table lists the default RBAC alerting role assignments to the basic roles: + +| Basic role | Associated fixed roles | Description | +| ---------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| Admin | `fixed:alerting:writer`
`fixed:alerting.provisioning.secrets:reader`
`fixed:alerting.provisioning:writer` | Default [Grafana organization administrator](ref:rbac-basic-roles) assignments. | +| Editor | `fixed:alerting:writer`
`fixed:alerting.provisioning.provenance:writer` | Default [Editor](ref:rbac-basic-roles) assignments. | +| Viewer | `fixed:alerting:reader` | Default [Viewer](ref:rbac-basic-roles) assignments. | + ### Grafana OnCall roles If you are using [Grafana OnCall](ref:oncall), you can try out the integration between Grafana OnCall and RBAC. diff --git a/docs/sources/alerting/alerting-rules/alerting-migration.md b/docs/sources/alerting/alerting-rules/alerting-migration.md index 3afa3aec453..320b04b4643 100644 --- a/docs/sources/alerting/alerting-rules/alerting-migration.md +++ b/docs/sources/alerting/alerting-rules/alerting-migration.md @@ -134,7 +134,7 @@ To convert data source-managed alert rules to Grafana managed alerts: Pausing stops alert rule evaluation behavior for the newly created Grafana-managed alert rules. -9. (Optional) In the **Target data source** of the **Recording rules** section, you can select the data source that the imported recording rules will query. By default, it is the data source selected in the **Data source** dropdown. +9. (Optional) In the **Target data source** of the **Recording rules** section, you can select the data source to which the imported recording rules will write metrics. By default, it is the data source selected in the **Data source** dropdown. 10. Click **Import**. @@ -242,6 +242,8 @@ Set to `true` to import recording rules in paused state. The UID of the data source to use for alert rule queries. +If not specified in the header, Grafana uses the configured default from `unified_alerting.prometheus_conversion.default_datasource_uid`. If neither the header nor the configuration option is provided, the request fails. + #### `X-Grafana-Alerting-Target-Datasource-UID` The UID of the target data source for recording rules. If not specified, the value from `X-Grafana-Alerting-Datasource-UID` is used. diff --git a/docs/sources/alerting/alerting-rules/create-recording-rules/_index.md b/docs/sources/alerting/alerting-rules/create-recording-rules/_index.md index a56d3ac5bb2..bcf9663aca9 100644 --- a/docs/sources/alerting/alerting-rules/create-recording-rules/_index.md +++ b/docs/sources/alerting/alerting-rules/create-recording-rules/_index.md @@ -48,6 +48,14 @@ Recording rules can be helpful in various scenarios, such as: The evaluation group of the recording rule determines how often the metric is pre-computed. +## Recommendations + +- **Use frequent evaluation intervals**. Set frequent evaluation intervals for recording rules. Long intervals, such as an hour, can cause the recorded metric to be stale and lead to misaligned alert rule evaluations, especially when combined with a long pending period. +- **Align alert evaluation with recording frequency**. The evaluation interval of an alert rule that depends on a recorded metric should be aligned with the recording rule's interval. If a recording rule runs every 3 minutes, the alert rule should also be evaluated at a similar frequency to ensure it acts on fresh data. +- **Use `_over_time` functions for instant queries**. Since all alert rules are ultimately executed as an instant query, you can use functions like `max_over_time(my_metric[5m])` as an instant query. This allows you to get an aggregated value over a period without using a range query and a reduce expression. + +## Types of recording rules + Similar to alert rules, Grafana supports two types of recording rules: 1. [Grafana-managed recording rules](ref:grafana-managed-recording-rules), which can query any Grafana data source supported by alerting. It's the recommended option. diff --git a/docs/sources/alerting/best-practices/_index.md b/docs/sources/alerting/best-practices/_index.md deleted file mode 100644 index 4e08dd8ef37..00000000000 --- a/docs/sources/alerting/best-practices/_index.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/ -description: This section provides a set of guides for useful alerting practices and recommendations -keywords: - - grafana -labels: - products: - - cloud - - enterprise - - oss -menuTitle: Best practices -title: Grafana Alerting best practices -weight: 170 ---- - -# Grafana Alerting best practices - -This section provides a set of guides and examples of best practices for Grafana Alerting. Here you can learn more about how to handle common alert management problems and you can see examples of more advanced usage of Grafana Alerting. - -{{< section >}} - -Designing and configuring an alert management set up that works takes time. Here are some additional tips on how to create an effective alert management set up: - -{{< shared id="alert-planning-fundamentals" >}} - -**Which are the key metrics for your business that you want to monitor and alert on?** - -- Find events that are important to know about and not so trivial or frequent that recipients ignore them. -- Alerts should only be created for big events that require immediate attention or intervention. -- Consider quality over quantity. - -**How do you want to organize your alerts and notifications?** - -- Be selective about who you set to receive alerts. Consider sending them to the right teams, whoever is on call, and the specific channels. -- Think carefully about priority and severity levels. -- Automate as far as possible provisioning Alerting resources with the API or Terraform. - -**Which information should you include in notifications?** - -- Consider who the alert receivers and responders are. -- Share information that helps responders identify and address potential issues. -- Link alerts to dashboards to guide responders on which data to investigate. - -**How can you reduce alert fatigue?** - -- Avoid noisy, unnecessary alerts by using silences, mute timings, or pausing alert rule evaluation. -- Continually tune your alert rules to review effectiveness. Remove alert rules to avoid duplication or ineffective alerts. -- Continually review your thresholds and evaluation rules. - -**How should you configure recording rules?** - -- Use frequent evaluation intervals. It is recommended to set a frequent evaluation interval for recording rules. Long intervals, such as an hour, can cause the recorded metric to be stale and lead to misaligned alert rule evaluations, especially when combined with a long pending period. -- Understand query types. Grafana Alerting uses both **Instant** and **Range** queries. Instant queries fetch a single data point, while Range queries fetch a series of data points over time. When using a Range query in an alert condition, you must use a Reduce expression to aggregate the series into a single value. -- Align alert evaluation with recording frequency. The evaluation interval of an alert rule that depends on a recorded metric should be aligned with the recording rule's interval. If a recording rule runs every 3 minutes, the alert rule should also be evaluated at a similar frequency to ensure it acts on fresh data. -- Use `_over_time` functions for instant queries. Since all alert rules are ultimately executed as an instant query, you can use functions like `max_over_time(my_metric[1h])` as an instant query. This allows you to get an aggregated value over a period without using a range query and a reduce expression. - -{{< /shared >}} diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-alertmanager.md b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-alertmanager.md index 4cdc84ec366..f34a9eeb654 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-alertmanager.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-alertmanager.md @@ -59,9 +59,9 @@ For more details on contact points, including how to test them and enable notifi ## Alertmanager settings -| Option | Description | -| ------ | ---------------------------------------------------------------------------------------------------------------------------------- | -| URL | The Alertmanager URL. This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. | +| Option | Description | +| ------ | ----------------------------------------------------------------------------------------------------------------- | +| URL | The Alertmanager URL. This field is [protected](ref:configure-contact-points) from modification in Grafana Cloud. | #### Optional settings diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-jira.md b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-jira.md index 659341405f1..9f68f70ae08 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-jira.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-jira.md @@ -49,14 +49,14 @@ For more details on contact points, including how to test them and enable notifi ### Required Settings -| Key | Description | -| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| URL | The URL of the REST API of your Jira instance. Supported versions: `2` and `3` (e.g., `https://your-domain.atlassian.net/rest/api/3`). This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. | -| Basic Auth User | Username for authentication. For Jira Cloud, use your email address. | -| Basic Auth Password | Password or personal token. For Jira Cloud, you need to obtain a personal token [here](https://id.atlassian.com/manage-profile/security/api-tokens) and use it as the password. | -| API Token | An alternative to basic authentication, a bearer token is used to authorize the API requests. See [Jira documentation](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html) for more information. | -| Project Key | The project key identifying the project where issues will be created. Project keys are unique identifiers for a project. | -| Issue Type | The type of issue to create (e.g., `Task`, `Bug`, `Incident`). Make sure that you specify a type that is available in your project. | +| Key | Description | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| URL | The URL of the REST API of your Jira instance. Supported versions: `2` and `3` (e.g., `https://your-domain.atlassian.net/rest/api/3`). This field is [protected](ref:configure-contact-points) from modification in Grafana Cloud. | +| Basic Auth User | Username for authentication. For Jira Cloud, use your email address. | +| Basic Auth Password | Password or personal token. For Jira Cloud, you need to obtain a personal token [here](https://id.atlassian.com/manage-profile/security/api-tokens) and use it as the password. | +| API Token | An alternative to basic authentication, a bearer token is used to authorize the API requests. See [Jira documentation](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html) for more information. | +| Project Key | The project key identifying the project where issues will be created. Project keys are unique identifiers for a project. | +| Issue Type | The type of issue to create (e.g., `Task`, `Bug`, `Incident`). Make sure that you specify a type that is available in your project. | ### Optional Settings diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-mqtt.md b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-mqtt.md index 6f76a574619..3f6a403d27a 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-mqtt.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-mqtt.md @@ -54,10 +54,10 @@ For more details on contact points, including how to test them and enable notifi ### Required Settings -| Option | Description | -| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -| Broker URL | The URL of the MQTT broker. This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. | -| Topic | The topic to which the message will be sent. | +| Option | Description | +| ---------- | ----------------------------------------------------------------------------------------------------------------------- | +| Broker URL | The URL of the MQTT broker. This field is [protected](ref:configure-contact-points) from modification in Grafana Cloud. | +| Topic | The topic to which the message will be sent. | ### Optional Settings diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-slack.md b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-slack.md index 8f56174ed60..3bda324ec23 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-slack.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-slack.md @@ -51,8 +51,8 @@ You can customize the `title` and `body` of the Slack message using [notificatio If you are using a Slack API Token, complete the following steps. -1. Follow steps 1 and 2 of the [Slack API Quickstart](https://api.slack.com/start/quickstart). -1. Add the [chat:write.public](https://api.slack.com/scopes/chat:write.public) scope to give your app the ability to post in all public channels without joining. +1. Follow step 1 of the [Slack API Quickstart](https://docs.slack.dev/app-management/quickstart-app-settings/#creating) to create the app. +1. Continue onto the second step of the [Slack API Quickstart](https://docs.slack.dev/app-management/quickstart-app-settings/#scopes) and add the [chat:write.public](https://api.slack.com/scopes/chat:write.public) scope as described to give your app the ability to post in all public channels without joining. 1. In OAuth Tokens for Your Workspace, copy the Bot User OAuth Token. 1. Open your Slack workplace. 1. Right click the channel you want to receive notifications in. diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md index 120a45be2a2..d24b54fc568 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md @@ -62,9 +62,9 @@ For more details on contact points, including how to test them and enable notifi ## Webhook settings -| Option | Description | -| ------ | ----------------------------------------------------------------------------------------------------------------------------- | -| URL | The Webhook URL. This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. | +| Option | Description | +| ------ | ------------------------------------------------------------------------------------------------------------ | +| URL | The Webhook URL. This field is [protected](ref:configure-contact-points) from modification in Grafana Cloud. | #### Optional settings diff --git a/docs/sources/alerting/examples/_index.md b/docs/sources/alerting/examples/_index.md new file mode 100644 index 00000000000..3b46838b78a --- /dev/null +++ b/docs/sources/alerting/examples/_index.md @@ -0,0 +1,22 @@ +--- +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/ +description: This section provides a set of guides for useful alerting practices and recommendations +keywords: + - grafana +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Examples +title: Examples +weight: 180 +--- + +# Examples + +This section provides practical examples that show how to work with different types of alerting data, apply alert design patterns, reuse alert logic, and take advantage of specific Grafana Alerting features. + +This section includes: + +{{< section >}} diff --git a/docs/sources/alerting/best-practices/dynamic-labels.md b/docs/sources/alerting/examples/dynamic-labels.md similarity index 98% rename from docs/sources/alerting/best-practices/dynamic-labels.md rename to docs/sources/alerting/examples/dynamic-labels.md index 7a9586ea6d9..6223e7ebff6 100644 --- a/docs/sources/alerting/best-practices/dynamic-labels.md +++ b/docs/sources/alerting/examples/dynamic-labels.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/dynamic-labels +aliases: + - ../best-practices/dynamic-labels/ # /docs/grafana//alerting/best-practices/dynamic-labels/ +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/dynamic-labels description: This example shows how to define dynamic labels based on query values, along with important behavior to keep in mind when using them. keywords: - grafana @@ -10,7 +12,7 @@ labels: - cloud - enterprise - oss -menuTitle: Examples of dynamic labels +menuTitle: Dynamic labels title: Example of dynamic labels in alert instances weight: 1104 refs: diff --git a/docs/sources/alerting/best-practices/dynamic-thresholds.md b/docs/sources/alerting/examples/dynamic-thresholds.md similarity index 97% rename from docs/sources/alerting/best-practices/dynamic-thresholds.md rename to docs/sources/alerting/examples/dynamic-thresholds.md index e749bc1d943..5ce850842a4 100644 --- a/docs/sources/alerting/best-practices/dynamic-thresholds.md +++ b/docs/sources/alerting/examples/dynamic-thresholds.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/dynamic-thresholds +aliases: + - ../best-practices/dynamic-thresholds/ # /docs/grafana//alerting/best-practices/dynamic-thresholds/ +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/dynamic-thresholds description: This example shows how to use a distinct threshold value per dimension using multi-dimensional alerts and a Math expression. keywords: - grafana @@ -10,7 +12,7 @@ labels: - cloud - enterprise - oss -menuTitle: Examples of dynamic thresholds +menuTitle: Dynamic thresholds title: Example of dynamic thresholds per dimension weight: 1105 refs: diff --git a/docs/sources/alerting/best-practices/high-cardinality-alerts.md b/docs/sources/alerting/examples/high-cardinality-alerts.md similarity index 97% rename from docs/sources/alerting/best-practices/high-cardinality-alerts.md rename to docs/sources/alerting/examples/high-cardinality-alerts.md index 9df60ac6bc6..74d080fbee5 100644 --- a/docs/sources/alerting/best-practices/high-cardinality-alerts.md +++ b/docs/sources/alerting/examples/high-cardinality-alerts.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/high-cardinality-alerts/ +aliases: + - ../best-practices/high-cardinality-alerts/ # /docs/grafana//alerting/best-practices/high-cardinality-alerts/ +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/high-cardinality-alerts/ description: Learn how to detect and alert on high-cardinality metrics that can overload your metrics backend and increase observability costs. keywords: - grafana @@ -8,7 +10,7 @@ labels: - cloud - enterprise - oss -menuTitle: Examples of high-cardinality alerts +menuTitle: High-cardinality alerts title: Examples of high-cardinality alerts weight: 1105 refs: diff --git a/docs/sources/alerting/best-practices/multi-dimensional-alerts.md b/docs/sources/alerting/examples/multi-dimensional-alerts.md similarity index 96% rename from docs/sources/alerting/best-practices/multi-dimensional-alerts.md rename to docs/sources/alerting/examples/multi-dimensional-alerts.md index f612df6aa37..fa6d7dd04c1 100644 --- a/docs/sources/alerting/best-practices/multi-dimensional-alerts.md +++ b/docs/sources/alerting/examples/multi-dimensional-alerts.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/multi-dimensional-alerts/ +aliases: + - ../best-practices/multi-dimensional-alerts/ # /docs/grafana//alerting/best-practices/multi-dimensional-alerts/ +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/multi-dimensional-alerts/ description: This example shows how a single alert rule can generate multiple alert instances using time series data. keywords: - grafana @@ -8,7 +10,7 @@ labels: - cloud - enterprise - oss -menuTitle: Examples of multi-dimensional alerts +menuTitle: Multi-dimensional alerts title: Example of multi-dimensional alerts on time series data weight: 1101 refs: diff --git a/docs/sources/alerting/best-practices/table-data.md b/docs/sources/alerting/examples/table-data.md similarity index 96% rename from docs/sources/alerting/best-practices/table-data.md rename to docs/sources/alerting/examples/table-data.md index a39530ef5a8..342475cb7fa 100644 --- a/docs/sources/alerting/best-practices/table-data.md +++ b/docs/sources/alerting/examples/table-data.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/table-data +aliases: + - ../best-practices/table-data/ # /docs/grafana//alerting/best-practices/table-data/ +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/table-data description: This example shows how to create an alert rule using table data. keywords: - grafana @@ -8,7 +10,7 @@ labels: - cloud - enterprise - oss -menuTitle: Examples of table data +menuTitle: Table data title: Example of alerting on tabular data weight: 1102 refs: diff --git a/docs/sources/alerting/best-practices/trace-based-alerts.md b/docs/sources/alerting/examples/trace-based-alerts.md similarity index 98% rename from docs/sources/alerting/best-practices/trace-based-alerts.md rename to docs/sources/alerting/examples/trace-based-alerts.md index d908ecd7385..974089b4643 100644 --- a/docs/sources/alerting/best-practices/trace-based-alerts.md +++ b/docs/sources/alerting/examples/trace-based-alerts.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/trace-based-alerts/ +aliases: + - ../best-practices/trace-based-alerts/ # /docs/grafana//alerting/best-practices/trace-based-alerts/ +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/trace-based-alerts/ description: This guide provides introductory examples and distinct approaches for setting up trace-based alerts in Grafana. keywords: - grafana @@ -8,7 +10,7 @@ labels: - cloud - enterprise - oss -title: Examples of trace-based alerts +title: Trace-based alerts weight: 1103 refs: testdata-data-source: diff --git a/docs/sources/alerting/best-practices/tutorials.md b/docs/sources/alerting/examples/tutorials.md similarity index 87% rename from docs/sources/alerting/best-practices/tutorials.md rename to docs/sources/alerting/examples/tutorials.md index fbef5f36797..97fa7d6a754 100644 --- a/docs/sources/alerting/best-practices/tutorials.md +++ b/docs/sources/alerting/examples/tutorials.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/tutorials/ +aliases: + - ../best-practices/tutorials/ # /docs/grafana//alerting/best-practices/tutorials/ +canonical: https://grafana.com/docs/grafana/latest/alerting/examples/tutorials/ description: This section provides a set of step-by-step tutorials guides to get started with Grafana Aletings. keywords: - grafana diff --git a/docs/sources/alerting/guides/_index.md b/docs/sources/alerting/guides/_index.md new file mode 100644 index 00000000000..69875878533 --- /dev/null +++ b/docs/sources/alerting/guides/_index.md @@ -0,0 +1,35 @@ +--- +canonical: https://grafana.com/docs/grafana/latest/alerting/guides/ +description: This section provides a set of guides for useful alerting practices and recommendations +keywords: + - grafana +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Guides +title: Guides +weight: 170 +refs: + examples: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/examples/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/examples/ + tutorials: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/examples/tutorials/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/examples/tutorials/ +--- + +# Guides + +Guides in the Grafana Alerting documentation provide best practices and practical recommendations to help you move from a basic alerting setup to real-world use cases. + +These guides cover topics such as: + +{{< section >}} + +For more hands-on examples, refer to [Examples](ref:examples) and [Tutorials](ref:tutorials). diff --git a/docs/sources/alerting/guides/best-practices.md b/docs/sources/alerting/guides/best-practices.md new file mode 100644 index 00000000000..d1010390569 --- /dev/null +++ b/docs/sources/alerting/guides/best-practices.md @@ -0,0 +1,201 @@ +--- +aliases: + - ../best-practices/ # /docs/grafana//alerting/best-practices/ +canonical: https://grafana.com/docs/grafana/latest/alerting/guides/best-practices/ +description: Designing and configuring an effective alerting system takes time. This guide focuses on building alerting systems that scale with real-world operations. +keywords: + - grafana + - alerting + - guide +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Best practices +title: Best practices +weight: 1010 +refs: + recovery-threshold: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/alert-rules/queries-conditions/#recovery-threshold + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/fundamentals/alert-rules/queries-conditions/#recovery-threshold + keep-firing-for: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/alert-rule-evaluation/#keep-firing-for + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/fundamentals/alert-rule-evaluation/#keep-firing-for + pending-period: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/alert-rule-evaluation/#pending-period + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/fundamentals/alert-rule-evaluation/#pending-period + silences: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/configure-notifications/create-silence/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/create-silence/ + timing-options: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/notifications/group-alert-notifications/#timing-options + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/notifications/group-alert-notifications/#timing-options + group-alert-notifications: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/notifications/group-alert-notifications/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/notifications/group-alert-notifications/ + notification-policies: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/notifications/notification-policies/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/notifications/notification-policies/ + annotations: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/alert-rules/annotation-label/#annotations + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/annotation-label/#annotations + multi-dimensional-alerts: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/examples/multi-dimensional-alerts/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/examples/multi-dimensional-alerts/ +--- + +# Alerting best practices + +Designing and configuring an effective alerting system takes time. This guide focuses on building alerting systems that scale with real-world operations. + +The practices described here are intentionally high-level and apply regardless of tooling. Whether you use Prometheus, Grafana Alerting, or another stack, the same constraints apply: complex systems, imperfect signals, and humans on call. + +Alerting is never finished. It evolves with incidents, organizational changes, and the systems it’s meant to protect. + +{{< shared id="alert-planning-fundamentals" >}} + +## Prioritize symptoms, but don’t ignore infrastructure signals + +Alerts should primarily detect user-facing failures, not internal component behavior. Users don't care that a pod restarted; they care when the application is slow or failing. Symptom-based alerts tie directly to user impact. + +Reliability metrics that impact users—latency, errors, availability—are better paging signals than infrastructure events or internal errors. + +That said, infrastructure signals still matter. They can act as early warning indicators and are often useful when alerting maturity is low. A sustained spike in CPU or memory usage might not justify a page, but it can help explain or anticipate symptom-based failures. + +Infrastructure alerts tend to be noisy and are often ignored when treated like paging signals. They are usually better suited for lower-severity channels such as dashboards, alert lists, or non-paging destinations like a dedicated Slack channel, where they can be monitored without interrupting on-call. + +The key is balance as your alerting matures. Use infrastructure alerts to support diagnosis and prevention, not as a replacement for symptom-based alerts. + +## Escalate priority based on confidence + +Alert priority is often tied to user impact and the urgency to respond, but confidence should determine when escalation is necessary. + +In this context, escalation defines how responders are notified as confidence grows. This can include increasing alert priority, widening notification, paging additional responders, or opening an incident once intervention is clearly required. + +Early signals are often ambiguous, and confidence in a non-transient failure is usually low. Paging too early creates noise; paging too late means users are impacted for longer before anyone acts. A small or sudden increase in latency may not justify immediate action, but it can indicate a failure in progress. + +Confidence increases as signals become stronger or begin to correlate. + +Escalation is justified when issues are sustained or reinforced by multiple signals. For example, high latency combined with a rising error rate, or the same event firing over a sustained period. These patterns reduce the chance of transient noise and increase the likelihood of real impact. + +Use confidence in user impact to drive escalation and avoid unnecessary pages. + +## Scope alerts for scalability and actionability + +In distributed systems, avoid creating separate alert rules for every host, service, or endpoint. Instead, define alert rules that scale automatically using [multi-dimensional alert rules](ref:multi-dimensional-alerts). This reduces rule duplication and allows alerting to scale as the system grows. + +Start simple. Default to a single dimension such as `service` or `endpoint` to keep alerts manageable. Add dimensions only when they improve actionability. For example, when missing a dimension like `region` hides failures or doesn't provide enough information to act quickly. + +Additional dimensions like `region` or `instance` can help identify the root cause, but more isn't always better. + +## Design alerts for first responders and clear actions + +Alerts should be designed for the first responder, not the person who created the alert. Anyone on call should be able to understand what's wrong and what to do next without deep knowledge of the system or alert configuration. + +Avoid vague alerts that force responders to spend time figuring out context. Every alert should clearly explain why it exists, what triggered it, and how to investigate. Use [annotations](ref:annotations) to link to relevant dashboards and runbooks, which are essential for faster resolution. + +Alerts should indicate a real problem and be actionable, even if the impact is low. Informational alerts add noise without improving reliability. + +If no action is possible, it shouldn't be an alert—consider using a dashboard instead. Over time, alerts behave like technical debt: easy to create, costly to maintain, and hard to remove. + +Review alerts often and remove those that don’t lead to action. + +## Alerts should have an owner and system scope + +Alerts without ownership are often ignored. Every alert must have an owner: a team responsible for maintaining the alert and responding when it fires. + +Alerts must also define a system scope, such as a service or infrastructure component. Scope provides organizational context and connects alerts with ownership. Defining clear scopes is easier when services are treated as first-class entities, and organizations are built around service ownership. + +> [Service Center in Grafana Cloud](/docs/grafana-cloud/alerting-and-irm/service-center/) can help operate a service-oriented view of your system and align alert scope with ownership. + +After scope, ownership, and alert priority are defined, routing determines where alerts go and how they escalate. **Notification routing is as important as the alerts**. + +Alerts should be delivered to the right team and channel based on priority, ownership, and team workflows. Use [notification policies](ref:notification-policies) to define a routing tree that matches the context of your service or scope: + +- Define a parent policy for default routing within the scope. +- Define nested policies for specific cases or higher-priority issues. + +## Prevent notification overload with alert grouping + +Without alert grouping, responders can receive many notifications for the same underlying problem. + +For example, a database failure can trigger several alerts at the same time like increased latency, higher error rates, and internal errors. Paging separately for each symptom quickly turns into notification spam, even though there is a single root cause. + +[Notification grouping](ref:group-alert-notifications) consolidates related alerts into a single notification. Instead of receiving multiple pages for the same issue, responders get one alert that represents the incident and includes all related firing alerts. + +Grouping should follow operational boundaries such as service or owner, as defined by notification policies. Downstream or cascading failures should be grouped together so they surface as one issue rather than many. + +## Mitigate flapping alerts + +Short-lived failure spikes often trigger alerts that auto-resolve quickly. Alerting on transient failures creates noise and leads responders to ignore them. + +Require issues to persist before alerting. Set a [pending period](ref:pending-period) to define how long a condition must remain true before firing. For example, instead of alerting immediately on high error rate, require it to stay above the threshold for some minutes. + +Also, stabilize alerts by tuning query ranges and aggregations. Using raw data makes alerts sensitive to noise. Instead, evaluate over a time window and aggregate the data to smooth short spikes. + +```promql +# Reacts to transient spikes. Avoid this. +cpu_usage > 90 + +# Smooth fluctuations. +avg_over_time(cpu_usage[5m]) > 90 +``` + +For latency and error-based alerts, percentiles are often more useful than averages: + +```promql +quantile_over_time(0.95, http_duration_seconds[5m]) > 3 +``` + +Finally, avoid rapid resolve-and-fire notifications by using [`keep_firing_for`](ref:keep-firing-for) or [recovery thresholds](ref:recovery-threshold) to keep alerts active briefly during recovery. Both options reduce flapping and unnecessary notifications. + +## Graduate symptom-based alerts into SLOs + +When a symptom-based alert fires frequently, it usually indicates a reliability concern that should be measured and managed more deliberately. This is often a sign that the alert could evolve into an [SLO](/docs/grafana-cloud/alerting-and-irm/slo/). + +Traditional alerts create pressure to react immediately, while error budgets introduce a buffer of time to act, changing how urgency is handled. Alerts can then be defined in terms of error budget burn rate rather than reacting to every minor deviation. + +SLOs also align distinct teams around common reliability goals by providing a shared definition of what "good" looks like. They help consolidate multiple symptom alerts into a single user-facing objective. + +For example, instead of several teams alerting on high latency, a single SLO can be used across teams to capture overall API performance. + +## Integrate alerting into incident post-mortems + +Every incident is an opportunity to improve alerting. After each incident, evaluate whether alerts helped responders act quickly or added unnecessary noise. + +Assess which alerts fired, and how they influenced incident response. Review whether alerts triggered too late, too early, or without enough context, and adjust thresholds, priority, or escalation based on what actually happened. + +Use [silences](ref:silences) during active incidents to reduce repeated notifications, but scope them carefully to avoid silencing unrelated alerts. + +Post-mortems should evaluate alerts with root causes and lessons learned. If responders lacked key information during the incident, enrich alerts with additional context, dashboards, or better guidance. + +## Alerts should be continuously improved + +Alerting is an iterative process. Alerts that aren’t reviewed and refined lose effectiveness as systems and traffic patterns change. + +Schedule regular reviews of existing alerts. Remove alerts that don’t lead to action, and tune alerts or thresholds that fire too often without providing useful signal. Reduce false positives to combat alert fatigue. + +Prioritize clarity and simplicity in alert design. Simpler alerts are easier to understand, maintain, and trust under pressure. Favor fewer high-quality, actionable alerts over a large number of low-value ones. + +Use dashboards and observability tools for investigation, not alerts. + +{{< /shared >}} diff --git a/docs/sources/alerting/best-practices/connectivity-errors.md b/docs/sources/alerting/guides/connectivity-errors.md similarity index 98% rename from docs/sources/alerting/best-practices/connectivity-errors.md rename to docs/sources/alerting/guides/connectivity-errors.md index 42d992b0cb0..18e12f5bc49 100644 --- a/docs/sources/alerting/best-practices/connectivity-errors.md +++ b/docs/sources/alerting/guides/connectivity-errors.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/connectivity-errors/ +aliases: + - ../best-practices/connectivity-errors/ # /docs/grafana//alerting/best-practices/connectivity-errors/ +canonical: https://grafana.com/docs/grafana/latest/alerting/guides/connectivity-errors/ description: Learn how to detect and handle connectivity issues in alerts using Prometheus, Grafana Alerting, or both. keywords: - grafana @@ -14,7 +16,7 @@ labels: - oss menuTitle: Handle connectivity errors title: Handle connectivity errors in alerts -weight: 1010 +weight: 1020 refs: pending-period: - pattern: /docs/grafana/ diff --git a/docs/sources/alerting/best-practices/missing-data.md b/docs/sources/alerting/guides/missing-data.md similarity index 98% rename from docs/sources/alerting/best-practices/missing-data.md rename to docs/sources/alerting/guides/missing-data.md index 06346ce3d05..c2d2500cdfd 100644 --- a/docs/sources/alerting/best-practices/missing-data.md +++ b/docs/sources/alerting/guides/missing-data.md @@ -1,5 +1,7 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/missing-data/ +aliases: + - ../best-practices/missing-data/ # /docs/grafana//alerting/best-practices/missing-data/ +canonical: https://grafana.com/docs/grafana/latest/alerting/guides/missing-data/ description: Learn how to detect missing metrics and design alerts that handle gaps in data in Prometheus and Grafana Alerting. keywords: - grafana @@ -14,7 +16,7 @@ labels: - oss menuTitle: Handle missing data title: Handle missing data in Grafana Alerting -weight: 1020 +weight: 1030 refs: connectivity-errors-guide: - pattern: /docs/grafana/ diff --git a/docs/sources/alerting/monitor-status/view-alert-rules.md b/docs/sources/alerting/monitor-status/view-alert-rules.md index b60ede12328..e5410d48765 100644 --- a/docs/sources/alerting/monitor-status/view-alert-rules.md +++ b/docs/sources/alerting/monitor-status/view-alert-rules.md @@ -41,9 +41,13 @@ Select a group to expand it and view the list of alert rules within that group. The list view includes a number of filters to simplify managing large volumes of alerts. +## Filter and save searches + Click the **Filter** button to open the filter popup. You can filter by name, label, folder/namespace, evaluation group, data source, contact point, rule source, rule state, rule type, and the health of the alert rule from the popup menu. Click **Apply** at the bottom of the filter popup to enact the filters as you search. -{{< figure src="/media/docs/alerting/alerting-list-view-filter.png" max-width="750px" alt="Alert rule filter options" >}} +Click the **Saved searches** button to open the list of previously saved searches, or click **+ Save current search** to add your current search to the saved searches list. You can also rename a saved search or set it as a default search. When you set a saved search as the default search, the Alert rules page opens with the search applied. + +{{< figure src="/media/docs/alerting/alerting-saved-searches.png" max-width="750px" alt="Alert rule filter options" >}} ## Change alert rules list view diff --git a/docs/sources/alerting/set-up/configure-alert-state-history/index.md b/docs/sources/alerting/set-up/configure-alert-state-history/index.md index 6ab7f817d92..dfb476b69ef 100644 --- a/docs/sources/alerting/set-up/configure-alert-state-history/index.md +++ b/docs/sources/alerting/set-up/configure-alert-state-history/index.md @@ -62,6 +62,9 @@ The following steps describe a basic configuration: # The URL of the Loki server loki_remote_url = http://localhost:3100 + + [feature_toggles] + enable = alertingCentralAlertHistory ``` 1. **Configure the Loki data source in Grafana** diff --git a/docs/sources/alerting/set-up/configure-rbac/_index.md b/docs/sources/alerting/set-up/configure-rbac/_index.md index 33fb9e57dcb..6e3338bab0b 100644 --- a/docs/sources/alerting/set-up/configure-rbac/_index.md +++ b/docs/sources/alerting/set-up/configure-rbac/_index.md @@ -17,54 +17,166 @@ weight: 155 # Configure RBAC -Role-based access control (RBAC) for Grafana Enterprise and Grafana Cloud provides a standardized way of granting, changing, and revoking access, so that users can view and modify Grafana resources. +[Role-based access control (RBAC)](/docs/grafana/latest/administration/roles-and-permissions/access-control/plan-rbac-rollout-strategy/) for Grafana Enterprise and Grafana Cloud provides a standardized way of granting, changing, and revoking access, so that users can view and modify Grafana resources. -A user is any individual who can log in to Grafana. Each user is associated with a role that includes permissions. Permissions determine the tasks a user can perform in the system. +A user is any individual who can log in to Grafana. Each user has a role that includes permissions. Permissions determine the tasks a user can perform in the system. Each permission contains one or more actions and a scope. +## Role types + +Grafana has three types of roles for managing access: + +- **Basic roles**: Admin, Editor, Viewer, and No basic role. These are assigned to users and provide default access levels. +- **Fixed roles**: Predefined groups of permissions for specific use cases. Basic roles automatically include certain fixed roles. +- **Custom roles**: User-defined roles that combine specific permissions for granular access control. + +## Basic role permissions + +The following table summarizes the default alerting permissions for each basic role. + +| Capability | Admin | Editor | Viewer | +| ----------------------------------------- | :---: | :----: | :----: | +| View alert rules | ✓ | ✓ | ✓ | +| Create, edit, and delete alert rules | ✓ | ✓ | | +| View silences | ✓ | ✓ | ✓ | +| Create, edit, and expire silences | ✓ | ✓ | | +| View contact points and templates | ✓ | ✓ | ✓ | +| Create, edit, and delete contact points | ✓ | ✓ | | +| View notification policies | ✓ | ✓ | ✓ | +| Create, edit, and delete policies | ✓ | ✓ | | +| View mute timings | ✓ | ✓ | ✓ | +| Create, edit, and delete timing intervals | ✓ | ✓ | | +| Access provisioning API | ✓ | ✓ | | +| Export with decrypted secrets | ✓ | | | + +{{< admonition type="note" >}} +Access to alert rules also requires permission to read the folder containing the rules and permission to query the data sources used in the rules. +{{< /admonition >}} + ## Permissions -Grafana Alerting has the following permissions. +Grafana Alerting has the following permissions organized by resource type. -| Action | Applicable scope | Description | -| -------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `alert.instances.external:read` | `datasources:*`
`datasources:uid:*` | Read alerts and silences in data sources that support alerting. | -| `alert.instances.external:write` | `datasources:*`
`datasources:uid:*` | Manage alerts and silences in data sources that support alerting. | -| `alert.instances:create` | n/a | Create silences in the current organization. | -| `alert.instances:read` | n/a | Read alerts and silences in the current organization. | -| `alert.instances:write` | n/a | Update and expire silences in the current organization. | -| `alert.notifications.external:read` | `datasources:*`
`datasources:uid:*` | Read templates, contact points, notification policies, and mute timings in data sources that support alerting. | -| `alert.notifications.external:write` | `datasources:*`
`datasources:uid:*` | Manage templates, contact points, notification policies, and mute timings in data sources that support alerting. | -| `alert.notifications:write` | n/a | Manage templates, contact points, notification policies, and mute timings in the current organization. | -| `alert.notifications:read` | n/a | Read all templates, contact points, notification policies, and mute timings in the current organization. | -| `alert.rules.external:read` | `datasources:*`
`datasources:uid:*` | Read alert rules in data sources that support alerting (Prometheus, Mimir, and Loki) | -| `alert.rules.external:write` | `datasources:*`
`datasources:uid:*` | Create, update, and delete alert rules in data sources that support alerting (Mimir and Loki). | -| `alert.rules:create` | `folders:*`
`folders:uid:*` | Create Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. | -| `alert.rules:delete` | `folders:*`
`folders:uid:*` | Delete Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder. | -| `alert.rules:read` | `folders:*`
`folders:uid:*` | Read Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder. | -| `alert.rules:write` | `folders:*`
`folders:uid:*` | Update Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder. To allow query modifications add `datasources:query` in the scope of data sources the user can query. | -| `alert.silences:create` | `folders:*`
`folders:uid:*` | Create rule-specific silences in a folder and its subfolders. | -| `alert.silences:read` | `folders:*`
`folders:uid:*` | Read all general silences and rule-specific silences in a folder and its subfolders. | -| `alert.silences:write` | `folders:*`
`folders:uid:*` | Update and expire rule-specific silences in a folder and its subfolders. | -| `alert.provisioning:read` | n/a | Read all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and data source are not required. | -| `alert.provisioning.secrets:read` | n/a | Same as `alert.provisioning:read` plus ability to export resources with decrypted secrets. | -| `alert.provisioning:write` | n/a | Update all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and data source are not required. | -| `alert.provisioning.provenance:write` | n/a | Set provisioning status for alerting resources. Cannot be used alone. Requires user to have permissions to access resources | -| `alert.notifications.receivers:read` | `receivers:*`
`receivers:uid:*` | Read contact points. | -| `alert.notifications.receivers.secrets:read` | `receivers:*`
`receivers:uid:*` | Export contact points with decrypted secrets. | -| `alert.notifications.receivers:create` | n/a | Create a new contact points. The creator is automatically granted full access to the created contact point. | -| `alert.notifications.receivers:write` | `receivers:*`
`receivers:uid:*` | Update existing contact points. | -| `alert.notifications.receivers:delete` | `receivers:*`
`receivers:uid:*` | Update and delete existing contact points. | -| `receivers.permissions:read` | `receivers:*`
`receivers:uid:*` | Read permissions for contact points. | -| `receivers.permissions:write` | `receivers:*`
`receivers:uid:*` | Manage permissions for contact points. | -| `alert.notifications.time-intervals:read` | n/a | Read mute time intervals. | -| `alert.notifications.time-intervals:write` | n/a | Create new or update existing mute time intervals. | -| `alert.notifications.time-intervals:delete` | n/a | Delete existing time intervals. | -| `alert.notifications.templates:read` | n/a | Read templates. | -| `alert.notifications.templates:write` | n/a | Create new or update existing templates. | -| `alert.notifications.templates:delete` | n/a | Delete existing templates. | -| `alert.notifications.routes:read` | n/a | Read notification policies. | -| `alert.notifications.routes:write` | n/a | Create new, update and update notification policies. | +### Alert rules + +Permissions for managing Grafana-managed alert rules. + +| Action | Applicable scope | Description | +| -------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `alert.rules:create` | `folders:*`
`folders:uid:*` | Create Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. | +| `alert.rules:read` | `folders:*`
`folders:uid:*` | Read Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder. | +| `alert.rules:write` | `folders:*`
`folders:uid:*` | Update Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder. To allow query modifications add `datasources:query` in the scope of data sources the user can query. | +| `alert.rules:delete` | `folders:*`
`folders:uid:*` | Delete Grafana alert rules in a folder and its subfolders. Combine this permission with `folders:read` in a scope that includes the folder. | + +### External alert rules + +Permissions for managing alert rules in external data sources that support alerting. + +| Action | Applicable scope | Description | +| ---------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------------------- | +| `alert.rules.external:read` | `datasources:*`
`datasources:uid:*` | Read alert rules in data sources that support alerting (Prometheus, Mimir, and Loki). | +| `alert.rules.external:write` | `datasources:*`
`datasources:uid:*` | Create, update, and delete alert rules in data sources that support alerting (Mimir and Loki). | + +### Alert instances and silences + +Permissions for managing alert instances and silences in Grafana. + +| Action | Applicable scope | Description | +| ------------------------ | ------------------------------ | ------------------------------------------------------------------------------------ | +| `alert.instances:read` | n/a | Read alerts and silences in the current organization. | +| `alert.instances:create` | n/a | Create silences in the current organization. | +| `alert.instances:write` | n/a | Update and expire silences in the current organization. | +| `alert.silences:read` | `folders:*`
`folders:uid:*` | Read all general silences and rule-specific silences in a folder and its subfolders. | +| `alert.silences:create` | `folders:*`
`folders:uid:*` | Create rule-specific silences in a folder and its subfolders. | +| `alert.silences:write` | `folders:*`
`folders:uid:*` | Update and expire rule-specific silences in a folder and its subfolders. | + +### External alert instances + +Permissions for managing alert instances in external data sources. + +| Action | Applicable scope | Description | +| -------------------------------- | -------------------------------------- | ----------------------------------------------------------------- | +| `alert.instances.external:read` | `datasources:*`
`datasources:uid:*` | Read alerts and silences in data sources that support alerting. | +| `alert.instances.external:write` | `datasources:*`
`datasources:uid:*` | Manage alerts and silences in data sources that support alerting. | + +### Contact points + +Permissions for managing contact points (notification receivers). + +| Action | Applicable scope | Description | +| -------------------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `alert.notifications.receivers:list` | n/a | List contact points in the current organization. | +| `alert.notifications.receivers:read` | `receivers:*`
`receivers:uid:*` | Read contact points. | +| `alert.notifications.receivers.secrets:read` | `receivers:*`
`receivers:uid:*` | Export contact points with decrypted secrets. | +| `alert.notifications.receivers:create` | n/a | Create a new contact points. The creator is automatically granted full access to the created contact point. | +| `alert.notifications.receivers:write` | `receivers:*`
`receivers:uid:*` | Update existing contact points. | +| `alert.notifications.receivers:delete` | `receivers:*`
`receivers:uid:*` | Update and delete existing contact points. | +| `alert.notifications.receivers:test` | `receivers:*`
`receivers:uid:*` | Test contact points to verify their configuration. | +| `receivers.permissions:read` | `receivers:*`
`receivers:uid:*` | Read permissions for contact points. | +| `receivers.permissions:write` | `receivers:*`
`receivers:uid:*` | Manage permissions for contact points. | + +### Notification policies + +Permissions for managing notification policies (routing rules). + +| Action | Applicable scope | Description | +| ---------------------------------- | ---------------- | ----------------------------------------------------- | +| `alert.notifications.routes:read` | n/a | Read notification policies. | +| `alert.notifications.routes:write` | n/a | Create new, update, and delete notification policies. | + +### Time intervals + +Permissions for managing mute time intervals. + +| Action | Applicable scope | Description | +| ------------------------------------------- | ---------------- | -------------------------------------------------- | +| `alert.notifications.time-intervals:read` | n/a | Read mute time intervals. | +| `alert.notifications.time-intervals:write` | n/a | Create new or update existing mute time intervals. | +| `alert.notifications.time-intervals:delete` | n/a | Delete existing time intervals. | + +### Templates + +Permissions for managing notification templates. + +| Action | Applicable scope | Description | +| ------------------------------------------ | ---------------- | ------------------------------------------------------------------------------- | +| `alert.notifications.templates:read` | n/a | Read templates. | +| `alert.notifications.templates:write` | n/a | Create new or update existing templates. | +| `alert.notifications.templates:delete` | n/a | Delete existing templates. | +| `alert.notifications.templates.test:write` | n/a | Test templates with custom payloads (preview and payload editor functionality). | + +### General notifications + +Legacy permissions for managing all notification resources. + +| Action | Applicable scope | Description | +| --------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------- | +| `alert.notifications:read` | n/a | Read all templates, contact points, notification policies, and mute timings in the current organization. | +| `alert.notifications:write` | n/a | Manage templates, contact points, notification policies, and mute timings in the current organization. | + +### External notifications + +Permissions for managing notification resources in external data sources. + +| Action | Applicable scope | Description | +| ------------------------------------ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `alert.notifications.external:read` | `datasources:*`
`datasources:uid:*` | Read templates, contact points, notification policies, and mute timings in data sources that support alerting. | +| `alert.notifications.external:write` | `datasources:*`
`datasources:uid:*` | Manage templates, contact points, notification policies, and mute timings in data sources that support alerting. | + +### Provisioning + +Permissions for managing alerting resources via the provisioning API. + +| Action | Applicable scope | Description | +| ---------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `alert.provisioning:read` | n/a | Read all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and data source are not required. | +| `alert.provisioning.secrets:read` | n/a | Same as `alert.provisioning:read` plus ability to export resources with decrypted secrets. | +| `alert.provisioning:write` | n/a | Update all Grafana alert rules, notification policies, etc via provisioning API. Permissions to folders and data source are not required. | +| `alert.rules.provisioning:read` | n/a | Read Grafana alert rules via provisioning API. More specific than `alert.provisioning:read`. | +| `alert.rules.provisioning:write` | n/a | Create, update, and delete Grafana alert rules via provisioning API. More specific than `alert.provisioning:write`. | +| `alert.notifications.provisioning:read` | n/a | Read notification resources (contact points, notification policies, templates, time intervals) via provisioning API. More specific than `alert.provisioning:read`. | +| `alert.notifications.provisioning:write` | n/a | Create, update, and delete notification resources via provisioning API. More specific than `alert.provisioning:write`. | +| `alert.provisioning.provenance:write` | n/a | Set provisioning status for alerting resources. Cannot be used alone. Requires user to have permissions to access resources. | To help plan your RBAC rollout strategy, refer to [Plan your RBAC rollout strategy](https://grafana.com/docs/grafana/next/administration/roles-and-permissions/access-control/plan-rbac-rollout-strategy/). diff --git a/docs/sources/alerting/set-up/configure-rbac/access-folders/index.md b/docs/sources/alerting/set-up/configure-rbac/access-folders/index.md index 10fb63385ff..825629089cb 100644 --- a/docs/sources/alerting/set-up/configure-rbac/access-folders/index.md +++ b/docs/sources/alerting/set-up/configure-rbac/access-folders/index.md @@ -16,7 +16,7 @@ title: Manage access using folders or data sources weight: 200 --- -## Manage access using folders or data sources +# Manage access using folders or data sources You can extend the access provided by a role to alert rules and rule-specific silences by assigning permissions to individual folders or data sources. diff --git a/docs/sources/alerting/set-up/configure-rbac/access-roles/index.md b/docs/sources/alerting/set-up/configure-rbac/access-roles/index.md index 668e84c41cb..b3c51d4f866 100644 --- a/docs/sources/alerting/set-up/configure-rbac/access-roles/index.md +++ b/docs/sources/alerting/set-up/configure-rbac/access-roles/index.md @@ -55,16 +55,16 @@ Details of the fixed roles and the access they provide for Grafana Alerting are | Full read-only access: `fixed:alerting:reader` | All permissions from `fixed:alerting.rules:reader`
`fixed:alerting.instances:reader`
`fixed:alerting.notifications:reader` | Read alert rules, alert instances, silences, contact points, and notification policies in Grafana and external providers. | | Read via Provisioning API + Export Secrets: `fixed:alerting.provisioning.secrets:reader` | `alert.provisioning:read` and `alert.provisioning.secrets:read` | Read alert rules, alert instances, silences, contact points, and notification policies using the provisioning API and use export with decrypted secrets. | | Access to alert rules provisioning API: `fixed:alerting.provisioning:writer` | `alert.provisioning:read` and `alert.provisioning:write` | Manage all alert rules, notification policies, contact points, templates, in the organization using the provisioning API. | -| Set provisioning status: `fixed:alerting.provisioning.status:writer` | `alert.provisioning.provenance:write` | Set provisioning rules for Alerting resources. Should be used together with other regular roles (Notifications Writer and/or Rules Writer.) | +| Set provisioning status: `fixed:alerting.provisioning.provenance:writer` | `alert.provisioning.provenance:write` | Set provisioning rules for Alerting resources. Should be used together with other regular roles (Notifications Writer and/or Rules Writer.) | | Contact Point Reader: `fixed:alerting.receivers:reader` | `alert.notifications.receivers:read` for scope `receivers:*` | Read all contact points. | | Contact Point Creator: `fixed:alerting.receivers:creator` | `alert.notifications.receivers:create` | Create a new contact point. The user is automatically granted full access to the created contact point. | | Contact Point Writer: `fixed:alerting.receivers:writer` | `alert.notifications.receivers:read`, `alert.notifications.receivers:write`, `alert.notifications.receivers:delete` for scope `receivers:*` and
`alert.notifications.receivers:create` | Create a new contact point and manage all existing contact points. | | Templates Reader: `fixed:alerting.templates:reader` | `alert.notifications.templates:read` | Read all notification templates. | -| Templates Writer: `fixed:alerting.templates:writer` | `alert.notifications.templates:read`, `alert.notifications.templates:write`, `alert.notifications.templates:delete` | Create new and manage existing notification templates. | +| Templates Writer: `fixed:alerting.templates:writer` | `alert.notifications.templates:read`, `alert.notifications.templates:write`, `alert.notifications.templates:delete`, `alert.notifications.templates.test:write` | Create new and manage existing notification templates. Test templates with custom payloads. | | Time Intervals Reader: `fixed:alerting.time-intervals:reader` | `alert.notifications.time-intervals:read` | Read all time intervals. | | Time Intervals Writer: `fixed:alerting.time-intervals:writer` | `alert.notifications.time-intervals:read`, `alert.notifications.time-intervals:write`, `alert.notifications.time-intervals:delete` | Create new and manage existing time intervals. | -| Notification Policies Reader: `fixed:alerting.routes:reader` | `alert.notifications.routes:read` | Read all time intervals. | -| Notification Policies Writer: `fixed:alerting.routes:writer` | `alert.notifications.routes:read` `alert.notifications.routes:write` | Create new and manage existing time intervals. | +| Notification Policies Reader: `fixed:alerting.routes:reader` | `alert.notifications.routes:read` | Read all notification policies. | +| Notification Policies Writer: `fixed:alerting.routes:writer` | `alert.notifications.routes:read`
`alert.notifications.routes:write` | Create new and manage existing notification policies. | ## Create custom roles diff --git a/docs/sources/alerting/set-up/configure-roles/index.md b/docs/sources/alerting/set-up/configure-roles/index.md index 36adb865ab3..091d11de7bf 100644 --- a/docs/sources/alerting/set-up/configure-roles/index.md +++ b/docs/sources/alerting/set-up/configure-roles/index.md @@ -16,25 +16,27 @@ weight: 150 # Configure roles and permissions +This guide explains how to configure roles and permissions for Grafana Alerting for Grafana OSS users. You'll learn how to manage access using roles, folder permissions, and contact point permissions. + A user is any individual who can log in to Grafana. Each user is associated with a role that includes permissions. Permissions determine the tasks a user can perform in the system. For example, the Admin role includes permissions for an administrator to create and delete users. For more information, refer to [Organization roles](https://grafana.com/docs/grafana//administration/roles-and-permissions/#organization-roles). ## Manage access using roles -For Grafana OSS, there are three roles: Admin, Editor, and Viewer. +Grafana OSS has three roles: Admin, Editor, and Viewer. -Details of the roles and the access they provide for Grafana Alerting are below. +The following table describes the access each role provides for Grafana Alerting. -| Role | Access | -| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Admin | Write access to alert rules, notification resources (notification API, contact points, templates, time intervals, notification policies, and silences), and provisioning. | -| Editor | Write access to alert rules, notification resources (notification API, contact points, templates, time intervals, notification policies, and silences), and provisioning. | -| Viewer | Read access to alert rules, notification resources (notification API, contact points, templates, time intervals, notification policies, and silences). | +| Role | Access | +| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Viewer | Read access to alert rules, notification resources (notification API, contact points, templates, time intervals, notification policies, and silences). | +| Editor | Write access to alert rules, notification resources (notification API, contact points, templates, time intervals, notification policies, and silences), and provisioning. | +| Admin | Write access to alert rules, notification resources (notification API, contact points, templates, time intervals, notification policies, and silences), and provisioning, as well as assign roles. | ## Assign roles -To assign roles, admins need to complete the following steps. +To assign roles, an admin needs to complete the following steps. 1. Navigate to **Administration** > **Users and access** > **Users, Teams, or Service Accounts**. 1. Search for the user, team or service account you want to add a role for. @@ -58,32 +60,30 @@ Refer to the following table for details on the additional access provided by fo You can't use folders to customize access to notification resources. {{< /admonition >}} -To manage folder permissions, complete the following steps. +To manage folder permissions, complete the following steps: 1. In the left-side menu, click **Dashboards**. 1. Hover your mouse cursor over a folder and click **Go to folder**. 1. Click **Manage permissions** from the Folder actions menu. 1. Update or add permissions as required. -## Manage access using contact point permissions +## Manage access to contact points -### Before you begin - -Extend or limit the access provided by a role to contact points by assigning permissions to individual contact point. +Extend or limit the access provided by a role to contact points by assigning permissions to individual contact points. This allows different users, teams, or service accounts to have customized access to read or modify specific contact points. Refer to the following table for details on the additional access provided by contact point permissions. -| Folder permission | Additional Access | -| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| View | View and export contact point as well as select it on the Alert rule edit page | -| Edit | Update or delete the contact point | -| Admin | Same additional access as Edit and manage permissions for the contact point. User should have additional permissions to read users and teams. | +| Contact point permission | Additional Access | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | +| View | View and export contact point as well as select it on the Alert rule edit page | +| Edit | Update or delete the contact point | +| Admin | Same additional access as Edit and manage permissions for the contact point. User should have additional permissions to read users and teams. | -### Steps +### Assign contact point permissions -To contact point permissions, complete the following steps. +To manage contact point permissions, complete the following steps: 1. In the left-side menu, click **Contact points**. 1. Hover your mouse cursor over a contact point and click **More**. diff --git a/docs/sources/as-code/infrastructure-as-code/grafana-operator/manage-dashboards-argocd.md b/docs/sources/as-code/infrastructure-as-code/grafana-operator/manage-dashboards-argocd.md index 0531a0c803f..bfc369222c8 100644 --- a/docs/sources/as-code/infrastructure-as-code/grafana-operator/manage-dashboards-argocd.md +++ b/docs/sources/as-code/infrastructure-as-code/grafana-operator/manage-dashboards-argocd.md @@ -81,7 +81,7 @@ Replace the placeholders with your values: In your `grafana` directory, create a sub-folder called `dashboards`. -This guide shows you how to creates three separate dashboards. For all dashboard configurations, replace the placeholders with your values: +This guide shows you how to create three separate dashboards. For all dashboard configurations, replace the placeholders with your values: - _``_: Name of your Grafana Cloud Stack - _``_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster diff --git a/docs/sources/as-code/infrastructure-as-code/terraform/terraform-plugins.md b/docs/sources/as-code/infrastructure-as-code/terraform/terraform-plugins.md index f0626540ca3..eea698aace1 100644 --- a/docs/sources/as-code/infrastructure-as-code/terraform/terraform-plugins.md +++ b/docs/sources/as-code/infrastructure-as-code/terraform/terraform-plugins.md @@ -24,7 +24,7 @@ Before you begin, you should have the following available: - Administrator permissions in your Grafana instance; for more information on assigning Grafana RBAC roles, refer to [Assign RBAC roles](/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-control/assign-rbac-roles/). {{< admonition type="note" >}} -All of the following Terraform configuration files should be saved in the same directory. +Save all of the following Terraform configuration files in the same directory. {{< /admonition >}} ## Configure the Grafana provider diff --git a/docs/sources/as-code/observability-as-code/provision-resources/file-path-setup.md b/docs/sources/as-code/observability-as-code/provision-resources/file-path-setup.md index f2cd24a46b1..ca71a0c0d9c 100644 --- a/docs/sources/as-code/observability-as-code/provision-resources/file-path-setup.md +++ b/docs/sources/as-code/observability-as-code/provision-resources/file-path-setup.md @@ -54,7 +54,7 @@ For production systems, use the `folderFromFilesStructure` capability instead of ## Before you begin {{< admonition type="note" >}} -Enable the `provisioning` and `kubernetesDashboards` feature toggles in Grafana to use this feature. +Enable the `provisioning` feature toggle in Grafana to use this feature. {{< /admonition >}} To set up file provisioning, you need: @@ -67,7 +67,7 @@ To set up file provisioning, you need: ## Enable required feature toggles and configure permitted paths -To activate local file provisioning in Grafana, you need to enable the `provisioning` and `kubernetesDashboards` feature toggles. +To activate local file provisioning in Grafana, you need to enable the `provisioning` feature toggle. For additional information about feature toggles, refer to [Configure feature toggles](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/feature-toggles). The local setting must be a relative path and its relative path must be configured in the `permitted_provisioned_paths` configuration option. @@ -82,12 +82,11 @@ Any subdirectories are automatically included. The values that you enter for the `permitted_provisioning_paths` become the base paths for those entered when you enter a local path in the **Connect to local storage** wizard. 1. Open your Grafana configuration file, either `grafana.ini` or `custom.ini`. For file location based on operating system, refer to [Configuration file location](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles). -1. Locate or add a `[feature_toggles]` section. Add these values: +1. Locate or add a `[feature_toggles]` section. Add this value: ```ini [feature_toggles] provisioning = true - kubernetesDashboards = true ; use k8s from browser ``` 1. Locate or add a `[paths]` section. To add more than one location, use the pipe character (`|`) to separate the paths. The list should not include empty paths or trailing pipes. Add these values: @@ -129,35 +128,48 @@ The set up process verifies the path and provides an error message if a problem #### Synchronization limitations -Full instance sync is not available in Grafana Cloud. +{{< admonition type="caution" >}} -In Grafana OSS/Enterprise: +Full instance sync is not available in Grafana Cloud and is experimental and unsupported in Grafana OSS/Enterprise. + +{{< /admonition >}} + +To have access to full instance sync you must explicitly enable the option. + +The following applies: -- If you try to perform a full instance sync with resources that contain alerts or panels, the connection will be blocked. - You won't be able to create new alerts or library panels after setup is completed. - If you opted for full instance sync and want to use alerts and library panels, you'll have to delete the provisioned repository and connect again with folder sync. #### Set up synchronization -Choose to either sync your entire organization resources with external storage, or to sync certain resources to a new Grafana folder (with up to 10 connections). +You can sync external resources into a new folder without affecting the rest of your instance. -- Choose **Sync all resources with external storage** if you want to sync and manage your entire Grafana instance through external storage. With this option, all of your dashboards are synced to that one repository. You can only have one provisioned connection with this selection, and you won't have the option of setting up additional repositories to connect to. +To set up synchronization: -- Choose **Sync external storage to new Grafana folder** to sync external resources into a new folder without affecting the rest of your instance. You can repeat this process for up to 10 connections. +1. Select which resources you want to sync. -Next, enter a **Display name** for the repository connection. Resources stored in this connection appear under the chosen display name in the Grafana UI. +1. Enter a **Display name** for the repository connection. Resources stored in this connection appear under the chosen display name in the Grafana UI. -Click **Synchronize** to continue. +1. Click **Synchronize** to continue. + +1. You can repeat this process for up to 10 connections. + +{{< admonition type="note" >}} + +Optionally, you can export any unmanaged resources into the provisioned folder. See how in [Synchronize with external storage](#synchronize-with-external-storage). + +{{< /admonition >}} ### Synchronize with external storage -After this one time step, all future updates are automatically saved to the local file path and provisioned back to the instance. +In this step you proceed to synchronize the resources selected in the previous step. Optionally, you can check the **Migrate existing resources** box to migrate your unmanaged dashboards to the provisioned folder. -During the initial synchronization, your dashboards will be temporarily unavailable. No data or configurations will be lost. +Select **Begin synchronization** to start the process. After this one time step, all future updates are automatically saved to the local file path and provisioned back to the instance. + +Note that during the initial synchronization, your dashboards will be temporarily unavailable. No data or configurations will be lost. How long the process takes depends upon the number of resources involved. -Select **Begin synchronization** to start the process. - ### Choose additional settings If you wish, you can make any files synchronized as as **Read only** so no changes can be made to the resources through Grafana. diff --git a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/_index.md b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/_index.md new file mode 100644 index 00000000000..4e4e523bf35 --- /dev/null +++ b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/_index.md @@ -0,0 +1,147 @@ +--- +title: Git Sync deployment scenarios +menuTitle: Deployment scenarios +description: Learn about common Git Sync deployment patterns and configurations for different organizational needs +weight: 450 +keywords: + - git sync + - deployment patterns + - scenarios + - multi-environment + - teams +--- + +# Git Sync deployment scenarios + +This guide shows practical deployment scenarios for Grafana’s Git Sync. Learn how to configure bidirectional synchronization between Grafana and Git repositories for teams, environments, and regions. + +{{< admonition type="caution" >}} +Git Sync is an experimental feature. It reflects Grafana’s approach to Observability as Code and might include limitations or breaking changes. For current status and known limitations, refer to the [Git Sync introduction](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/intro-git-sync/). +{{< /admonition >}} + +## Understand the relationship between key Git Sync components + +Before you explore the scenarios, understand how the key Git Sync components relate: + +- [Grafana instance](#grafana-instance) +- [Git repository structure](#git-repository-structure) +- [Git Sync repository resource](#git-sync-repository-resource) + +### Grafana instance + +A Grafana instance is a running Grafana server. Multiple instances can: + +- Connect to the same Git repository using different Repository configurations. +- Sync from different branches of the same repository. +- Sync from different paths within the same repository. +- Sync from different repositories. + +### Git repository structure + +You can organize your Git repository in several ways: + +- Single branch, multiple paths: Use different directories for different purposes (for example, `dev/`, `prod/`, `team-a/`). +- Multiple branches: Use different branches for different environments or teams (for example, `main`, `develop`, `team-a`). +- Multiple repositories: Use separate repositories for different teams or environments. + +### Git Sync repository resource + +A repository resource is a Grafana configuration object that defines: + +- Which Git repository to sync with. +- Which branch to use. +- Which directory path to synchronize. +- Sync behavior and workflows. + +Each repository resource creates bidirectional synchronization between a Grafana instance and a specific location in Git. + +## How does repository sync behave? + +With Git Sync you configure a repository resource to sync with your Grafana instance: + +1. Grafana monitors the specified Git location (repository, branch, and path). +2. Grafana creates a folder in Dashboards (typically named after the repository). +3. Grafana creates dashboards from dashboard JSON files in Git within this folder. +4. Grafana commits dashboard changes made in the UI back to Git. +5. Grafana pulls dashboard changes made in Git and updates dashboards in the UI. +6. Synchronization occurs at regular intervals (configurable), or instantly if you use webhooks. + +You can find the provisioned dashboards organized in folders under **Dashboards**. + +## Example: Relationship between repository, branch, and path + +Here's a concrete example showing how the three parameters work together: + +**Configuration:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `team-platform/grafana/` + +**In Git (on branch `main`):** + +``` +your-org/grafana-manifests/ +├── .git/ +├── README.md +├── team-platform/ +│ └── grafana/ +│ ├── cpu-metrics.json ← Synced +│ ├── memory-usage.json ← Synced +│ └── disk-io.json ← Synced +├── team-data/ +│ └── grafana/ +│ └── pipeline-stats.json ← Not synced (different path) +└── other-files.txt ← Not synced (outside path) +``` + +**In Grafana Dashboards view:** + +``` +Dashboards +└── 📁 grafana-manifests/ + ├── CPU Metrics Dashboard + ├── Memory Usage Dashboard + └── Disk I/O Dashboard +``` + +**Key points:** + +- Grafana only synchronizes files within the specified path (`team-platform/grafana/`). +- Grafana ignores files in other paths or at the repository root. +- The folder name in Grafana comes from the repository name. +- Dashboard titles come from the JSON file content, not the filename. + +## Repository configuration flexibility + +Git Sync repositories support different combinations of repository URL, branch, and path: + +- Different Git repositories: Each environment or team can use its own repository. + - Instance A: `repository: your-org/grafana-prod`. + - Instance B: `repository: your-org/grafana-dev`. +- Different branches: Use separate branches within the same repository. + - Instance A: `repository: your-org/grafana-manifests, branch: main`. + - Instance B: `repository: your-org/grafana-manifests, branch: develop`. +- Different paths: Use different directory paths within the same repository. + - Instance A: `repository: your-org/grafana-manifests, branch: main, path: production/`. + - Instance B: `repository: your-org/grafana-manifests, branch: main, path: development/`. +- Any combination: Mix and match based on your workflow requirements. + +## Scenarios + +Use these deployment scenarios to plan your Git Sync setup: + +- [Single instance](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/single-instance/) +- [Git Sync for development and production environments](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/dev-prod/) +- [Git Sync with regional replication](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-region/) +- [High availability](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/high-availability/) +- [Git Sync in a shared Grafana instance](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-team/) + +## Learn more + +Refer to the following documents to learn more: + +- [Git Sync introduction](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/intro-git-sync/) +- [Git Sync setup guide](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-setup/) +- [Dashboard provisioning](https://grafana.com/docs/grafana//administration/provisioning/) +- [Observability as Code](https://grafana.com/docs/grafana//as-code/observability-as-code/) diff --git a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/dev-prod.md b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/dev-prod.md new file mode 100644 index 00000000000..3433c713024 --- /dev/null +++ b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/dev-prod.md @@ -0,0 +1,147 @@ +--- +title: Git Sync for development and production environments +menuTitle: Across environments +description: Use separate Grafana instances for development and production with Git-controlled promotion +weight: 20 +--- + +# Git Sync for development and production environments + +Use separate Grafana instances for development and production. Each syncs with different Git locations to test dashboards before production. + +## Use it for + +- **Staged deployments**: You need to test dashboard changes before production deployment. +- **Change control**: You require approvals before dashboards reach production. +- **Quality assurance**: You verify dashboard functionality in a non-production environment. +- **Risk mitigation**: You minimize the risk of breaking production dashboards. + +## Architecture + +``` +┌────────────────────────────────────────────────────────────┐ +│ GitHub Repository │ +│ Repository: your-org/grafana-manifests │ +│ Branch: main │ +│ │ +│ grafana-manifests/ │ +│ ├── dev/ │ +│ │ ├── dashboard-new.json ← Development dashboards │ +│ │ └── dashboard-test.json │ +│ │ │ +│ └── prod/ │ +│ ├── dashboard-stable.json ← Production dashboards │ +│ └── dashboard-approved.json │ +└────────────────────────────────────────────────────────────┘ + ↕ ↕ + Git Sync (dev/) Git Sync (prod/) + ↕ ↕ +┌─────────────────────┐ ┌─────────────────────┐ +│ Dev Grafana │ │ Prod Grafana │ +│ │ │ │ +│ Repository: │ │ Repository: │ +│ - path: dev/ │ │ - path: prod/ │ +│ │ │ │ +│ Creates folder: │ │ Creates folder: │ +│ "grafana-manifests"│ │ "grafana-manifests"│ +└─────────────────────┘ └─────────────────────┘ +``` + +## Repository structure + +**In Git:** + +``` +your-org/grafana-manifests +├── dev/ +│ ├── dashboard-new.json +│ └── dashboard-test.json +└── prod/ + ├── dashboard-stable.json + └── dashboard-approved.json +``` + +**In Grafana Dashboards view:** + +**Dev instance:** + +``` +Dashboards +└── 📁 grafana-manifests/ + ├── New Dashboard + └── Test Dashboard +``` + +**Prod instance:** + +``` +Dashboards +└── 📁 grafana-manifests/ + ├── Stable Dashboard + └── Approved Dashboard +``` + +- Both instances create a folder named "grafana-manifests" (from repository name) +- Each instance only shows dashboards from its configured path (`dev/` or `prod/`) +- Dashboards appear with their titles from the JSON files + +## Configuration parameters + +Development: + +- Repository: `your-org/grafana-manifests` +- Branch: `main` +- Path: `dev/` + +Production: + +- Repository: `your-org/grafana-manifests` +- Branch: `main` +- Path: `prod/` + +## How it works + +1. Developers create and modify dashboards in development. +2. Git Sync commits changes to `dev/`. +3. You review changes in Git. +4. You promote approved dashboards from `dev/` to `prod/`. +5. Production syncs from `prod/`. +6. Production dashboards update. + +## Alternative: Use branches + +Instead of using different paths, you can configure instances to use different branches: + +**Development instance:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `develop` +- **Path**: `grafana/` + +**Production instance:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `grafana/` + +With this approach: + +- Development changes go to the `develop` branch +- Use Git merge or pull request workflows to promote changes from `develop` to `main` +- Production automatically syncs from the `main` branch + +## Alternative: Use separate repositories for stricter isolation + +For stricter isolation, use completely separate repositories: + +**Development instance:** + +- **Repository**: `your-org/grafana-manifests-dev` +- **Branch**: `main` +- **Path**: `grafana/` + +**Production instance:** + +- **Repository**: `your-org/grafana-manifests-prod` +- **Branch**: `main` +- **Path**: `grafana/` diff --git a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/high-availability.md b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/high-availability.md new file mode 100644 index 00000000000..04575574ed4 --- /dev/null +++ b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/high-availability.md @@ -0,0 +1,217 @@ +--- +title: Git Sync for high availability environments +menuTitle: High availability +description: Run multiple Grafana instances serving traffic simultaneously, synchronized via Git Sync +weight: 50 +--- + +# Git Sync for high availability environments + +## Primary–replica scenario + +Use a primary Grafana instance and one or more replicas synchronized with the same Git location to enable failover. + +### Use it for + +- **Automatic failover**: You need service continuity when the primary instance fails. +- **High availability**: Your organization requires guaranteed dashboard availability. +- **Simple HA setup**: You want high availability without the complexity of active–active. +- **Maintenance windows**: You perform updates while another instance serves traffic. +- **Business continuity**: Dashboard access can't tolerate downtime. + +### Architecture + +``` +┌─────────────────────────────────────────────────────┐ +│ GitHub Repository │ +│ Repository: your-org/grafana-manifests │ +│ Branch: main │ +│ │ +│ grafana-manifests/ │ +│ └── shared/ │ +│ ├── dashboard-metrics.json │ +│ ├── dashboard-alerts.json │ +│ └── dashboard-logs.json │ +└─────────────────────────────────────────────────────┘ + ↕ ↕ + Git Sync (shared/) Git Sync (shared/) + ↕ ↕ +┌────────────────────┐ ┌────────────────────┐ +│ Master Grafana │ │ Replica Grafana │ +│ (Active) │ │ (Standby) │ +│ │ │ │ +│ Repository: │ │ Repository: │ +│ - path: shared/ │ │ - path: shared/ │ +└────────────────────┘ └────────────────────┘ + │ │ + └───────────┬───────────────────┘ + ↓ + ┌──────────────────────┐ + │ Reverse Proxy │ + │ (Failover) │ + └──────────────────────┘ +``` + +### Repository structure + +**In Git:** + +``` +your-org/grafana-manifests +└── shared/ + ├── dashboard-metrics.json + ├── dashboard-alerts.json + └── dashboard-logs.json +``` + +**In Grafana Dashboards view (both instances):** + +``` +Dashboards +└── 📁 grafana-manifests/ + ├── Metrics Dashboard + ├── Alerts Dashboard + └── Logs Dashboard +``` + +- Master and replica instances show identical folder structure. +- Both sync from the same `shared/` path. +- Reverse proxy routes traffic to master (active) instance. +- If master fails, proxy automatically fails over to replica (standby). +- Users see the same dashboards regardless of which instance is serving traffic. + +### Configuration parameters + +Both master and replica instances use identical parameters: + +**Master instance:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `shared/` + +**Replica instance:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `shared/` + +### How it works + +1. Both instances stay synchronized through Git. +2. Reverse proxy routes traffic to primary. +3. Users edit on primary. Git Sync commits changes. +4. Both instances pull latest changes to keep replica in sync. +5. On primary failure, proxy fails over to replica. + +### Failover considerations + +- Health checks and monitoring. +- Continuous syncing to minimize data loss. +- Plan failback (automatic or manual). + +## Load balancer scenario + +Run multiple active Grafana instances behind a load balancer. All instances sync from the same Git location. + +### Use it for + +- **High traffic**: Your deployment needs to handle significant user load. +- **Load distribution**: You want to distribute user requests across instances. +- **Maximum availability**: You need service continuity during maintenance or failures. +- **Scalability**: You want to add instances as load increases. +- **Performance**: Users need fast response times under heavy load. + +### Architecture + +``` +┌─────────────────────────────────────────────────────┐ +│ GitHub Repository │ +│ Repository: your-org/grafana-manifests │ +│ Branch: main │ +│ │ +│ grafana-manifests/ │ +│ └── shared/ │ +│ ├── dashboard-metrics.json │ +│ ├── dashboard-alerts.json │ +│ └── dashboard-logs.json │ +└─────────────────────────────────────────────────────┘ + ↕ ↕ + Git Sync (shared/) Git Sync (shared/) + ↕ ↕ +┌────────────────────┐ ┌────────────────────┐ +│ Grafana Instance 1│ │ Grafana Instance 2│ +│ (Active) │ │ (Active) │ +│ │ │ │ +│ Repository: │ │ Repository: │ +│ - path: shared/ │ │ - path: shared/ │ +└────────────────────┘ └────────────────────┘ + │ │ + └───────────┬───────────────────┘ + ↓ + ┌──────────────────────┐ + │ Load Balancer │ + │ (Round Robin) │ + └──────────────────────┘ +``` + +### Repository structure + +**In Git:** + +``` +your-org/grafana-manifests +└── shared/ + ├── dashboard-metrics.json + ├── dashboard-alerts.json + └── dashboard-logs.json +``` + +**In Grafana Dashboards view (all instances):** + +``` +Dashboards +└── 📁 grafana-manifests/ + ├── Metrics Dashboard + ├── Alerts Dashboard + └── Logs Dashboard +``` + +- All instances show identical folder structure. +- All instances sync from the same `shared/` path. +- Load balancer distributes requests across all active instances. +- Any instance can serve read requests. +- Any instance can accept dashboard modifications. +- Changes propagate to all instances through Git. + +### Configuration parameters + +All instances use identical parameters: + +**Instance 1:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `shared/` + +**Instance 2:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `shared/` + +### How it works + +1. All instances stay synchronized through Git. +2. Load balancer distributes incoming traffic across all active instances. +3. Users can view dashboards from any instance. +4. When a user modifies a dashboard on any instance, Git Sync commits the change. +5. All other instances pull the updated dashboard during their next sync cycle, or instantly if webhooks are configured. +6. If one instance fails, load balancer stops routing traffic to it and remaining instances continue serving. + +### Important considerations + +- **Eventually consistent**: Due to sync intervals, instances may briefly have different dashboard versions. +- **Concurrent edits**: Multiple users editing the same dashboard on different instances can cause conflicts. +- **Database sharing**: Instances should share the same backend database for user sessions, preferences, and annotations. +- **Stateless design**: Design for stateless operation where possible to maximize load balancing effectiveness. diff --git a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-region.md b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-region.md new file mode 100644 index 00000000000..ee699719560 --- /dev/null +++ b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-region.md @@ -0,0 +1,93 @@ +--- +title: Git Sync with regional replication +menuTitle: Regional replication +description: Synchronize multiple regional Grafana instances from a shared Git location +weight: 30 +--- + +# Git Sync with regional replication + +Deploy multiple Grafana instances across regions. Synchronize them with the same Git location to ensure consistent dashboards everywhere. + +## Use it for + +- **Geographic distribution**: You deploy Grafana close to users in different regions. +- **Latency reduction**: Users need fast dashboard access from their location. +- **Data sovereignty**: You keep dashboard data in specific regions. +- **High availability**: You need dashboard availability across regions. +- **Consistent experience**: All users see the same dashboards regardless of region. + +## Architecture + +``` +┌─────────────────────────────────────────────────────┐ +│ GitHub Repository │ +│ Repository: your-org/grafana-manifests │ +│ Branch: main │ +│ │ +│ grafana-manifests/ │ +│ └── shared/ │ +│ ├── dashboard-global.json │ +│ ├── dashboard-metrics.json │ +│ └── dashboard-logs.json │ +└─────────────────────────────────────────────────────┘ + ↕ ↕ + Git Sync (shared/) Git Sync (shared/) + ↕ ↕ +┌────────────────────┐ ┌────────────────────┐ +│ US Region │ │ EU Region │ +│ Grafana │ │ Grafana │ +│ │ │ │ +│ Repository: │ │ Repository: │ +│ - path: shared/ │ │ - path: shared/ │ +└────────────────────┘ └────────────────────┘ +``` + +## Repository structure + +**In Git:** + +``` +your-org/grafana-manifests +└── shared/ + ├── dashboard-global.json + ├── dashboard-metrics.json + └── dashboard-logs.json +``` + +**In Grafana Dashboards view (all regions):** + +``` +Dashboards +└── 📁 grafana-manifests/ + ├── Global Dashboard + ├── Metrics Dashboard + └── Logs Dashboard +``` + +- All regional instances (US, EU, etc.) show identical folder structure +- Same folder name "grafana-manifests" in every region +- Same dashboards synced from the `shared/` path appear everywhere +- Users in any region see the exact same dashboards with the same titles + +## Configuration parameters + +All regions: + +- Repository: `your-org/grafana-manifests` +- Branch: `main` +- Path: `shared/` + +## How it works + +1. All regional instances pull dashboards from `shared/`. +2. Any region’s change commits to Git. +3. Other regions pull updates during the next sync (or via webhooks). +4. Changes propagate across regions per sync interval. + +## Considerations + +- **Write conflicts**: If users in different regions modify the same dashboard simultaneously, Git uses last-write-wins. +- **Primary region**: Consider designating one region as the primary location for making dashboard changes. +- **Propagation time**: Changes propagate to all regions within the configured sync interval, or instantly if webhooks are configured. +- **Network reliability**: Ensure all regions have reliable connectivity to the Git repository. diff --git a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-team.md b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-team.md new file mode 100644 index 00000000000..4f5ecc85fd2 --- /dev/null +++ b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-team.md @@ -0,0 +1,169 @@ +--- +title: Multiple team Git Sync +menuTitle: Shared instance +description: Use multiple Git repositories with one Grafana instance, one repository per team +weight: 60 +--- + +# Git Sync in a Grafana instance shared by multiple teams + +Use a single Grafana instance with multiple Repository resources, one per team. Each team manages its own dashboards while sharing Grafana. + +## Use it for + +- **Team autonomy**: Different teams manage their own dashboards independently. +- **Organizational structure**: Dashboard organization aligns with team structure. +- **Resource efficiency**: Multiple teams share Grafana infrastructure. +- **Cost optimization**: You reduce infrastructure costs while maintaining team separation. +- **Collaboration**: Teams can view each other’s dashboards while managing their own. + +## Architecture + +``` +┌─────────────────────────┐ ┌─────────────────────────┐ +│ Platform Team Repo │ │ Data Team Repo │ +│ platform-dashboards │ │ data-dashboards │ +│ │ │ │ +│ platform-dashboards/ │ │ data-dashboards/ │ +│ └── grafana/ │ │ └── grafana/ │ +│ ├── k8s.json │ │ ├── pipeline.json │ +│ └── infra.json │ │ └── analytics.json │ +└─────────────────────────┘ └─────────────────────────┘ + ↕ ↕ + Git Sync (grafana/) Git Sync (grafana/) + ↕ ↕ + ┌──────────────────────────────────────┐ + │ Grafana Instance │ + │ │ + │ Repository 1: │ + │ - repo: platform-dashboards │ + │ → Creates "platform-dashboards" │ + │ │ + │ Repository 2: │ + │ - repo: data-dashboards │ + │ → Creates "data-dashboards" │ + └──────────────────────────────────────┘ +``` + +## Repository structure + +**In Git (separate repositories):** + +**Platform team repository:** + +``` +your-org/platform-dashboards +└── grafana/ + ├── dashboard-k8s.json + └── dashboard-infra.json +``` + +**Data team repository:** + +``` +your-org/data-dashboards +└── grafana/ + ├── dashboard-pipeline.json + └── dashboard-analytics.json +``` + +**In Grafana Dashboards view:** + +``` +Dashboards +├── 📁 platform-dashboards/ +│ ├── Kubernetes Dashboard +│ └── Infrastructure Dashboard +└── 📁 data-dashboards/ + ├── Pipeline Dashboard + └── Analytics Dashboard +``` + +- Two separate folders created (one per Repository resource). +- Folder names derived from repository names. +- Each team has complete control over their own repository. +- Teams can independently manage permissions, branches, and workflows in their repos. +- All teams can view each other's dashboards in Grafana but manage only their own. + +## Configuration parameters + +**Platform team repository:** + +- **Repository**: `your-org/platform-dashboards` +- **Branch**: `main` +- **Path**: `grafana/` + +**Data team repository:** + +- **Repository**: `your-org/data-dashboards` +- **Branch**: `main` +- **Path**: `grafana/` + +## How it works + +1. Each team has their own Git repository for complete autonomy. +2. Each repository resource in Grafana creates a separate folder. +3. Platform team dashboards sync from `your-org/platform-dashboards` repository. +4. Data team dashboards sync from `your-org/data-dashboards` repository. +5. Teams can independently manage their repository settings, access controls, and workflows. +6. All teams can view each other's dashboards in Grafana but edit only their own. + +## Scale to more teams + +Adding additional teams is straightforward. For a third team, create a new repository and configure: + +- **Repository**: `your-org/security-dashboards` +- **Branch**: `main` +- **Path**: `grafana/` + +This creates a new "security-dashboards" folder in the same Grafana instance. + +## Alternative: Shared repository with different paths + +For teams that prefer sharing a single repository, use different paths to separate team dashboards: + +**In Git:** + +``` +your-org/grafana-manifests +├── team-platform/ +│ ├── dashboard-k8s.json +│ └── dashboard-infra.json +└── team-data/ + ├── dashboard-pipeline.json + └── dashboard-analytics.json +``` + +**Configuration:** + +**Platform team:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `team-platform/` + +**Data team:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `team-data/` + +This approach provides simpler repository management but less isolation between teams. + +## Alternative: Different branches per team + +For teams wanting their own branch in a shared repository: + +**Platform team:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `team-platform` +- **Path**: `grafana/` + +**Data team:** + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `team-data` +- **Path**: `grafana/` + +This allows teams to use Git branch workflows for collaboration while sharing the same repository. diff --git a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/single-instance.md b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/single-instance.md new file mode 100644 index 00000000000..39371f7e7d6 --- /dev/null +++ b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/single-instance.md @@ -0,0 +1,86 @@ +--- +title: Single instance Git Sync +menuTitle: Single instance +description: Synchronize a single Grafana instance with a Git repository +weight: 10 +--- + +# Single instance Git Sync + +Use a single Grafana instance synchronized with a Git repository. This is the foundation for Git Sync and helps you understand bidirectional synchronization. + +## Use it for + +- **Getting started**: You want to learn how Git Sync works before implementing complex scenarios. +- **Personal projects**: Individual developers manage their own dashboards. +- **Small teams**: You have a simple setup without multiple environments or complex workflows. +- **Development environments**: You need quick prototyping and testing. + +## Architecture + +``` +┌─────────────────────────────────────────────────────┐ +│ GitHub Repository │ +│ Repository: your-org/grafana-manifests │ +│ Branch: main │ +│ │ +│ grafana-manifests/ │ +│ └── grafana/ │ +│ ├── dashboard-1.json │ +│ ├── dashboard-2.json │ +│ └── dashboard-3.json │ +└─────────────────────────────────────────────────────┘ + ↕ + Git Sync (bidirectional) + ↕ + ┌─────────────────────────────┐ + │ Grafana Instance │ + │ │ + │ Repository Resource: │ + │ - url: grafana-manifests │ + │ - branch: main │ + │ - path: grafana/ │ + │ │ + │ Creates folder: │ + │ "grafana-manifests" │ + └─────────────────────────────┘ +``` + +## Repository structure + +**In Git:** + +``` +your-org/grafana-manifests +└── grafana/ + ├── dashboard-1.json + ├── dashboard-2.json + └── dashboard-3.json +``` + +**In Grafana Dashboards view:** + +``` +Dashboards +└── 📁 grafana-manifests/ + ├── Dashboard 1 + ├── Dashboard 2 + └── Dashboard 3 +``` + +- A folder named "grafana-manifests" (from repository name) contains all synced dashboards. +- Each JSON file becomes a dashboard with its title displayed in the folder. +- Users browse dashboards organized under this folder structure. + +## Configuration parameters + +Configure your Grafana instance to synchronize with: + +- **Repository**: `your-org/grafana-manifests` +- **Branch**: `main` +- **Path**: `grafana/` + +## How it works + +1. **From Grafana to Git**: When users create or modify dashboards in Grafana, Git Sync commits changes to the `grafana/` directory on the `main` branch. +2. **From Git to Grafana**: When dashboard JSON files are added or modified in the `grafana/` directory, Git Sync pulls these changes into Grafana. diff --git a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-setup.md b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-setup.md index f6113fe428d..b43c279fb44 100644 --- a/docs/sources/as-code/observability-as-code/provision-resources/git-sync-setup.md +++ b/docs/sources/as-code/observability-as-code/provision-resources/git-sync-setup.md @@ -29,76 +29,70 @@ You can sign up to the private preview using the [Git Sync early access form](ht {{< /admonition >}} -Git Sync lets you manage Grafana dashboards as code by storing dashboard JSON files and folders in a remote GitHub repository. - -To set up Git Sync and synchronize with a GitHub repository follow these steps: - -1. [Enable feature toggles in Grafana](#enable-required-feature-toggles) (first time set up). -1. [Create a GitHub access token](#create-a-github-access-token). -1. [Configure a connection to your GitHub repository](#set-up-the-connection-to-github). -1. [Choose what content to sync with Grafana](#choose-what-to-synchronize). - -Optionally, you can [extend Git Sync](#configure-webhooks-and-image-rendering) by enabling pull request notifications and image previews of dashboard changes. - -| Capability | Benefit | Requires | -| ----------------------------------------------------- | ------------------------------------------------------------------------------- | -------------------------------------- | -| Adds a table summarizing changes to your pull request | Provides a convenient way to save changes back to GitHub. | Webhooks configured | -| Add a dashboard preview image to a PR | View a snapshot of dashboard changes to a pull request without opening Grafana. | Image renderer and webhooks configured | - -{{< admonition type="note" >}} - -Alternatively, you can configure a local file system instead of using GitHub. Refer to [Set up file provisioning](https://grafana.com/docs/grafana//observability-as-code/provision-resources/file-path-setup/) for more information. - -{{< /admonition >}} - -## Performance impacts of enabling Git Sync - -Git Sync is an experimental feature and is under continuous development. Reporting any issues you encounter can help us improve Git Sync. - -When Git Sync is enabled, the database load might increase, especially for instances with a lot of folders and nested folders. Evaluate the performance impact, if any, in a non-production environment. +This guide shows you how to set up Git Sync to synchronize your Grafana dashboards and folders with a GitHub repository. You'll set up Git Sync to enable version-controlled dashboard management either [using the UI](#set-up-git-sync-using-grafana-ui) or [as code](#set-up-git-sync-as-code). ## Before you begin -{{< admonition type="caution" >}} +Before you begin, ensure you have the following: -Refer to [Known limitations](https://grafana.com/docs/grafana//observability-as-code/provision-resources/intro-git-sync#known-limitations/) before using Git Sync. +- A Grafana instance (Cloud, OSS, or Enterprise). +- If you're [using webhooks or image rendering](#extend-git-sync-for-real-time-notification-and-image-rendering), a public instance with external access +- Administration rights in your Grafana organization +- A [GitHub private access token](#create-a-github-access-token) +- A GitHub repository to store your dashboards in +- Optional: The [Image Renderer service](https://github.com/grafana/grafana-image-renderer) to save image previews with your PRs + +### Known limitations + +Refer to [Known limitations](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/intro-git-sync#known-limitations) before using Git Sync. + +Refer to [Supported resources](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/intro-git-sync#supported-resources) for details about which resources you can sync. + +### Performance considerations + +When Git Sync is enabled, the database load might increase, especially for instances with many folders and nested folders. Evaluate the performance impact, if any, in a non-production environment. + +Git Sync is under continuous development. [Report any issues](https://grafana.com/help/) you encounter to help us improve Git Sync. + +## Set up Git Sync + +To set up Git Sync and synchronize with a GitHub repository, follow these steps: + +1. [Enable feature toggles in Grafana](#enable-required-feature-toggles) (first time setup) +1. [Create a GitHub access token](#create-a-github-access-token) +1. Set up Git Sync [using the UI](#set-up-git-sync-using-grafana-ui) or [as code](#set-up-git-sync-as-code) + +After setup, you can [verify your dashboards](#verify-your-dashboards-in-grafana). + +Optionally, you can also [extend Git Sync with webhooks and image rendering](#extend-git-sync-for-real-time-notification-and-image-rendering). + +{{< admonition type="note" >}} + +Alternatively, you can configure a local file system instead of using GitHub. Refer to [Set up file provisioning](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/file-path-setup/) for more information. {{< /admonition >}} -### Requirements - -To set up Git Sync, you need: - -- Administration rights in your Grafana organization. -- Enable the required feature toggles in your Grafana instance. Refer to [Enable required feature toggles](#enable-required-feature-toggles) for instructions. -- A GitHub repository to store your dashboards in. - - If you want to use a local file path, refer to [the local file path guide](https://grafana.com/docs/grafana//observability-as-code/provision-resources/file-path-setup/). -- A GitHub access token. The Grafana UI will prompt you during setup. -- Optional: A public Grafana instance. -- Optional: The [Image Renderer service](https://github.com/grafana/grafana-image-renderer) to save image previews with your PRs. - ## Enable required feature toggles -To activate Git Sync in Grafana, you need to enable the `provisioning` and `kubernetesDashboards` feature toggles. -For additional information about feature toggles, refer to [Configure feature toggles](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/feature-toggles). +To activate Git Sync in Grafana, you need to enable the `provisioning` feature toggle. For more information about feature toggles, refer to [Configure feature toggles](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles). -To enable the required feature toggles, add them to your Grafana configuration file: +To enable the required feature toggle: 1. Open your Grafana configuration file, either `grafana.ini` or `custom.ini`. For file location based on operating system, refer to [Configuration file location](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles). -1. Locate or add a `[feature_toggles]` section. Add these values: +1. Locate or add a `[feature_toggles]` section. Add this value: ```ini [feature_toggles] provisioning = true - kubernetesDashboards = true ; use k8s from browser ``` 1. Save the changes to the file and restart Grafana. ## Create a GitHub access token -Whenever you connect to a GitHub repository, you need to create a GitHub access token with specific repository permissions. -This token needs to be added to your Git Sync configuration to enable read and write permissions between Grafana and GitHub repository. +Whenever you connect to a GitHub repository, you need to create a GitHub access token with specific repository permissions. This token needs to be added to your Git Sync configuration to enable read and write permissions between Grafana and GitHub repository. + +To create a GitHub access token: 1. Create a new token using [Create new fine-grained personal access token](https://github.com/settings/personal-access-tokens/new). Refer to [Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) for instructions. 1. Under **Permissions**, expand **Repository permissions**. @@ -112,19 +106,23 @@ This token needs to be added to your Git Sync configuration to enable read and w 1. Verify the options and select **Generate token**. 1. Copy the access token. Leave the browser window available with the token until you've completed configuration. -GitHub Apps are not currently supported. +GitHub Apps aren't currently supported. -## Set up the connection to GitHub +## Set up Git Sync using Grafana UI -Use **Provisioning** to guide you through setting up Git Sync to use a GitHub repository. +1. [Configure a connection to your GitHub repository](#set-up-the-connection-to-github) +1. [Choose what content to sync with Grafana](#choose-what-to-synchronize) +1. [Choose additional settings](#choose-additional-settings) + +### Set up the connection to GitHub + +Use **Provisioning** to guide you through setting up Git Sync to use a GitHub repository: 1. Log in to your Grafana server with an account that has the Grafana Admin flag set. 1. Select **Administration** in the left-side menu and then **Provisioning**. 1. Select **Configure Git Sync**. -### Connect to external storage - -To connect your GitHub repository, follow these steps: +To connect your GitHub repository: 1. Paste your GitHub personal access token into **Enter your access token**. Refer to [Create a GitHub access token](#create-a-github-access-token) for instructions. 1. Paste the **Repository URL** for your GitHub repository into the text box. @@ -134,56 +132,217 @@ To connect your GitHub repository, follow these steps: ### Choose what to synchronize -In this step you can decide which elements to synchronize. Keep in mind the available options depend on the status of your Grafana instance. +You can sync external resources into a new folder without affecting the rest of your instance. -- If the instance contains resources in an incompatible data format, you'll have to migrate all the data using instance sync. Folder sync won't be supported. -- If there is already another connection using folder sync, instance sync won't be offered. +To set up synchronization: -#### Synchronization limitations +1. Select which resources you want to sync. -Git Sync only supports dashboards and folders. Alerts, panels, and other resources are not supported yet. +1. Enter a **Display name** for the repository connection. Resources stored in this connection appear under the chosen display name in the Grafana UI. -{{< admonition type="caution" >}} +1. Click **Synchronize** to continue. -Refer to [Known limitations](https://grafana.com/docs/grafana//observability-as-code/provision-resources/intro-git-sync#known-limitations/) before using Git Sync. Refer to [Supported resources](/docs/grafana//observability-as-code/provision-resources/intro-git-sync#supported-resources) for details about which resources you can sync. +1. You can repeat this process for up to 10 connections. + +{{< admonition type="note" >}} + +Optionally, you can export any unmanaged resources into the provisioned folder. See how in [Synchronize with external storage](#synchronize-with-external-storage). {{< /admonition >}} -Full instance sync is not available in Grafana Cloud. +#### Full instance sync -In Grafana OSS/Enterprise: +Full instance sync is not available in Grafana Cloud and is experimental and unsupported in Grafana OSS/Enterprise. -- If you try to perform a full instance sync with resources that contain alerts or panels, Git Sync will block the connection. -- You won't be able to create new alerts or library panels after the setup is completed. -- If you opted for full instance sync and want to use alerts and library panels, you'll have to delete the synced repository and connect again with folder sync. +To have access to this option you must enable experimental instance sync on purpose. -#### Set up synchronization +### Synchronize with external storage -To set up synchronization, choose to either sync your entire organization resources with external storage, or to sync certain resources to a new Grafana folder (with up to 10 connections). +After this one time step, all future updates are automatically saved to the Git repository and provisioned back to the instance. -- Choose **Sync all resources with external storage** if you want to sync and manage your entire Grafana instance through external storage. With this option, all of your dashboards are synced to that one repository. You can only have one provisioned connection with this selection, and you won't have the option of setting up additional repositories to connect to. -- Choose **Sync external storage to new Grafana folder** to sync external resources into a new folder without affecting the rest of your instance. You can repeat this process for up to 10 connections. - -Next, enter a **Display name** for the repository connection. Resources stored in this connection appear under the chosen display name in the Grafana UI. Click **Synchronize** to continue. +Check the **Migrate existing resources** box to migrate your unmanaged dashboards to the provisioned folder. ### Choose additional settings Finally, you can set up how often your configured storage is polled for updates. +To configure additional settings: + 1. For **Update instance interval (seconds)**, enter how often you want the instance to pull updates from GitHub. The default value is 60 seconds. 1. Optional: Select **Read only** to ensure resources can't be modified in Grafana. -1. Optional: If you have the Grafana Image Renderer plugin configured, you can **Enable dashboards previews in pull requests**. If image rendering is not available, then you can't select this option. For more information, refer to the [Image Renderer service](https://github.com/grafana/grafana-image-renderer). +1. Optional: If you have the Grafana Image Renderer plugin configured, you can **Enable dashboards previews in pull requests**. If image rendering isn't available, then you can't select this option. For more information, refer to the [Image Renderer service](https://github.com/grafana/grafana-image-renderer). 1. Select **Finish** to proceed. +### Modify your configuration after setup is complete + +To update your repository configuration after you've completed setup: + +1. Log in to your Grafana server with an account that has the Grafana Admin flag set. +1. Select **Administration** in the left-side menu and then **Provisioning**. +1. Select **Settings** for the repository you wish to modify. +1. Use the **Configure repository** screen to update any of the settings. +1. Select **Save** to preserve the updates. + +## Set up Git Sync as code + +Alternatively, you can also configure Git Sync using `grafanactl`. Since Git Sync configuration is managed as code using Custom Resource Definitions (CRDs), you can create a Repository CRD in a YAML file and use `grafanactl` to push it to Grafana. This approach enables automated, GitOps-style workflows for managing Git Sync configuration instead of using the Grafana UI. + +To set up Git Sync with `grafanactl`, follow these steps: + +1. [Create the repository CRD](#create-the-repository-crd) +1. [Push the repository CRD to Grafana](#push-the-repository-crd-to-grafana) +1. [Manage repository resources](#manage-repository-resources) +1. [Verify setup](#verify-setup) + +For more information, refer to the following documents: + +- [grafanactl Documentation](https://grafana.github.io/grafanactl/) +- [Repository CRD Reference](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-setup/) +- [Dashboard CRD Format](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/export-resources/) + +### Create the repository CRD + +Create a `repository.yaml` file defining your Git Sync configuration: + +```yaml +apiVersion: provisioning.grafana.app/v0alpha1 +kind: Repository +metadata: + name: +spec: + title: + type: github + github: + url: + branch: + path: grafana/ + generateDashboardPreviews: true + sync: + enabled: true + intervalSeconds: 60 + target: folder + workflows: + - write + - branch +secure: + token: + create: +``` + +Replace the placeholders with your values: + +- _``_: Unique identifier for this repository resource +- _``_: Human-readable name displayed in Grafana UI +- _``_: GitHub repository URL +- _``_: Branch to sync +- _``_: GitHub Personal Access Token + +{{< admonition type="note" >}} + +Only `target: folder` is currently supported for Git Sync. + +{{< /admonition >}} + +#### Configuration parameters + +The following configuration parameters are available: + +| Field | Description | +| --------------------------------------- | ----------------------------------------------------------- | +| `metadata.name` | Unique identifier for this repository resource | +| `spec.title` | Human-readable name displayed in Grafana UI | +| `spec.type` | Repository type (`github`) | +| `spec.github.url` | GitHub repository URL | +| `spec.github.branch` | Branch to sync | +| `spec.github.path` | Directory path containing dashboards | +| `spec.github.generateDashboardPreviews` | Generate preview images (true/false) | +| `spec.sync.enabled` | Enable synchronization (true/false) | +| `spec.sync.intervalSeconds` | Sync interval in seconds | +| `spec.sync.target` | Where to place synced dashboards (`folder`) | +| `spec.workflows` | Enabled workflows: `write` (direct commits), `branch` (PRs) | +| `secure.token.create` | GitHub Personal Access Token | + +### Push the repository CRD to Grafana + +Before pushing any resources, configure `grafanactl` with your Grafana instance details. Refer to the [grafanactl configuration documentation](https://grafana.github.io/grafanactl/) for setup instructions. + +Push the repository configuration: + +```sh +grafanactl resources push --path +``` + +The `--path` parameter has to point to the directory containing your `repository.yaml` file. + +After pushing, Grafana will: + +1. Create the repository resource +1. Connect to your GitHub repository +1. Pull dashboards from the specified path +1. Begin syncing at the configured interval + +### Manage repository resources + +#### List repositories + +To list all repositories: + +```sh +grafanactl resources get repositories +``` + +#### Get repository details + +To get details for a specific repository: + +```sh +grafanactl resources get repository/ +grafanactl resources get repository/ -o json +grafanactl resources get repository/ -o yaml +``` + +#### Update the repository + +To update a repository: + +```sh +grafanactl resources edit repository/ +``` + +#### Delete the repository + +To delete a repository: + +```sh +grafanactl resources delete repository/ +``` + +### Verify setup + +Check that Git Sync is working: + +```sh +# List repositories +grafanactl resources get repositories + +# Check Grafana UI +# Navigate to: Administration → Provisioning → Git Sync +``` + ## Verify your dashboards in Grafana To verify that your dashboards are available at the location that you specified, click **Dashboards**. The name of the dashboard is listed in the **Name** column. -Now that your dashboards have been synced from a repository, you can customize the name, change the branch, and create a pull request (PR) for it. Refer to [Manage provisioned repositories with Git Sync](https://grafana.com/docs/grafana//observability-as-code/provision-resources/use-git-sync/) for more information. +Now that your dashboards have been synced from a repository, you can customize the name, change the branch, and create a pull request (PR) for it. Refer to [Manage provisioned repositories with Git Sync](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/use-git-sync/) for more information. -## Configure webhooks and image rendering +## Extend Git Sync for real-time notification and image rendering -You can extend Git Sync by getting instant updates and pull requests using webhooks and add dashboard previews in pull requests. +Optionally, you can extend Git Sync by enabling pull request notifications and image previews of dashboard changes. + +| Capability | Benefit | Requires | +| ----------------------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------- | +| Adds a table summarizing changes to your pull request | Provides a convenient way to save changes back to GitHub | Webhooks configured | +| Add a dashboard preview image to a PR | View a snapshot of dashboard changes to a pull request without opening Grafana | Image renderer and webhooks configured | ### Set up webhooks for realtime notification and pull request integration @@ -191,25 +350,26 @@ When connecting to a GitHub repository, Git Sync uses webhooks to enable real-ti You can set up webhooks with whichever service or tooling you prefer. You can use Cloudflare Tunnels with a Cloudflare-managed domain, port-forwarding and DNS options, or a tool such as `ngrok`. -To set up webhooks you need to expose your Grafana instance to the public Internet. You can do this via port forwarding and DNS, a tool such as `ngrok`, or any other method you prefer. The permissions set in your GitHub access token provide the authorization for this communication. +To set up webhooks, you need to expose your Grafana instance to the public Internet. You can do this via port forwarding and DNS, a tool such as `ngrok`, or any other method you prefer. The permissions set in your GitHub access token provide the authorization for this communication. After you have the public URL, you can add it to your Grafana configuration file: -```yaml +```ini [server] -root_url = https://PUBLIC_DOMAIN.HERE +root_url = https:// ``` +Replace _``_ with your public domain. + To check the configured webhooks, go to **Administration** > **Provisioning** and click the **View** link for your GitHub repository. #### Expose necessary paths only -If your security setup does not permit publicly exposing the Grafana instance, you can either choose to `allowlist` the GitHub IP addresses, or expose only the necessary paths. +If your security setup doesn't permit publicly exposing the Grafana instance, you can either choose to allowlist the GitHub IP addresses, or expose only the necessary paths. The necessary paths required to be exposed are, in RegExp: - `/apis/provisioning\.grafana\.app/v0(alpha1)?/namespaces/[^/]+/repositories/[^/]+/(webhook|render/.*)$` - ### Set up image rendering for dashboard previews @@ -217,12 +377,14 @@ Set up image rendering to add visual previews of dashboard updates directly in p To enable this capability, install the Grafana Image Renderer in your Grafana instance. For more information and installation instructions, refer to the [Image Renderer service](https://github.com/grafana/grafana-image-renderer). -## Modify configurations after set up is complete +## Next steps -To update your repository configuration after you've completed set up: +You've successfully set up Git Sync to manage your Grafana dashboards through version control. Your dashboards are now synchronized with a GitHub repository, enabling collaborative development and change tracking. -1. Log in to your Grafana server with an account that has the Grafana Admin flag set. -1. Select **Administration** in the left-side menu and then **Provisioning**. -1. Select **Settings** for the repository you wish to modify. -1. Use the **Configure repository** screen to update any of the settings. -1. Select **Save** to preserve the updates. +To learn more about using Git Sync: + +- [Work with provisioned dashboards](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/provisioned-dashboards/) +- [Manage provisioned repositories with Git Sync](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/use-git-sync/) +- [Git Sync deployment scenarios](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios) +- [Export resources](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/export-resources/) +- [grafanactl documentation](https://grafana.github.io/grafanactl/) diff --git a/docs/sources/as-code/observability-as-code/provision-resources/intro-git-sync.md b/docs/sources/as-code/observability-as-code/provision-resources/intro-git-sync.md index 4d9bda529a3..903df6303a6 100644 --- a/docs/sources/as-code/observability-as-code/provision-resources/intro-git-sync.md +++ b/docs/sources/as-code/observability-as-code/provision-resources/intro-git-sync.md @@ -47,7 +47,7 @@ Using Git Sync, you can: {{< admonition type="caution" >}} -Git Sync only works with specific folders for the moment. Full-instance sync is not currently supported. +Full instance sync is not available in Grafana Cloud and is experimental and unsupported in Grafana OSS/Enterprise. {{< /admonition >}} @@ -84,7 +84,7 @@ Refer to [Requirements](https://grafana.com/docs/grafana//obser - You can only sync dashboards and folders. Refer to [Supported resources](#supported-resources) for more information. - If you're using Git Sync in Grafana OSS and Grafana Enterprise, some resources might be in an incompatible data format and won't be synced. -- Full-instance sync is not available in Grafana Cloud and has limitations in Grafana OSS and Grafana Enterprise. Refer to [Choose what to synchronize](../git-sync-setup/#choose-what-to-synchronize) for more details. +- Full-instance sync is not available in Grafana Cloud and is experimental in Grafana OSS and Grafana Enterprise. Refer to [Choose what to synchronize](../git-sync-setup/#choose-what-to-synchronize) for more details. - When migrating to full instance sync, during the synchronization process your resources will be temporarily unavailable. No one will be able to create, edit, or delete resources during this process. - If you want to manage existing resources with Git Sync, you need to save them as JSON files and commit them to the synced repository. Open a PR to import, copy, move, or save a dashboard. - Restoring resources from the UI is currently not possible. As an alternative, you can restore dashboards directly in your GitHub repository by raising a PR, and they will be updated in Grafana. @@ -127,7 +127,13 @@ An instance can be in one of the following Git Sync states: ## Common use cases -You can use Git Sync in the following scenarios. +{{< admonition type="note" >}} + +Refer to [Git Sync deployment scenarios](https://grafana.com/docs/grafana//as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios) for sample scenarios, including architecture and configuration details. + +{{< /admonition >}} + +You can use Git Sync for the following use cases: ### Version control and auditing diff --git a/docs/sources/as-code/observability-as-code/provision-resources/use-git-sync.md b/docs/sources/as-code/observability-as-code/provision-resources/use-git-sync.md index f7d37d4b94e..11ce2aee0aa 100644 --- a/docs/sources/as-code/observability-as-code/provision-resources/use-git-sync.md +++ b/docs/sources/as-code/observability-as-code/provision-resources/use-git-sync.md @@ -14,7 +14,7 @@ labels: - cloud title: Manage provisioned repositories with Git Sync menuTitle: Manage repositories with Git Sync -weight: 120 +weight: 400 canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/use-git-sync/ aliases: - ../../../observability-as-code/provision-resources/use-git-sync/ # /docs/grafana/next/observability-as-code/provision-resources/use-git-sync/ diff --git a/docs/sources/as-code/observability-as-code/schema-v2/_index.md b/docs/sources/as-code/observability-as-code/schema-v2/_index.md index 9be869a8391..65c73a49cbe 100644 --- a/docs/sources/as-code/observability-as-code/schema-v2/_index.md +++ b/docs/sources/as-code/observability-as-code/schema-v2/_index.md @@ -186,7 +186,7 @@ For the JSON and field usage notes, refer to the [links schema documentation](ht ### `tags` -The tags associated with the dashboard: +Tags associated with the dashboard. Each tag can be up to 50 characters long. ` [...string]` diff --git a/docs/sources/as-code/observability-as-code/schema-v2/links-schema.md b/docs/sources/as-code/observability-as-code/schema-v2/links-schema.md index 9598477354f..0ddc50376de 100644 --- a/docs/sources/as-code/observability-as-code/schema-v2/links-schema.md +++ b/docs/sources/as-code/observability-as-code/schema-v2/links-schema.md @@ -62,5 +62,6 @@ The table includes default and other fields: | targetBlank | bool. If true, the link will be opened in a new tab. Default is `false`. | | includeVars | bool. If true, includes current template variables values in the link as query params. Default is `false`. | | keepTime | bool. If true, includes current time range in the link as query params. Default is `false`. | +| placement? | string. Use placement to display the link somewhere else on the dashboard other than above the visualizations. Use the `inControlsMenu` parameter to render the link in the dashboard controls dropdown menu. | diff --git a/docs/sources/datasources/_index.md b/docs/sources/datasources/_index.md index e7da61ea2f5..28d46c9c600 100644 --- a/docs/sources/datasources/_index.md +++ b/docs/sources/datasources/_index.md @@ -112,6 +112,12 @@ For example, this video demonstrates the visual Prometheus query builder: For general information about querying in Grafana, and common options and user interface elements across all query editors, refer to [Query and transform data](ref:query-transform-data). +## Build a dashboard from the data source + +After you've configured a data source, you can start creating a dashboard directly from it, by clicking the **Build a dashboard** button. + +For more information, refer to [Begin dashboard creation from data source configuration](https://grafana.com/docs/grafana//visualizations/dashboards/build-dashboards/create-dashboard/#begin-dashboard-creation-from-connections). + ## Special data sources Grafana includes three special data sources: diff --git a/docs/sources/datasources/aws-cloudwatch/_index.md b/docs/sources/datasources/aws-cloudwatch/_index.md index bf3a14c590f..9cd5ed87a09 100644 --- a/docs/sources/datasources/aws-cloudwatch/_index.md +++ b/docs/sources/datasources/aws-cloudwatch/_index.md @@ -105,6 +105,11 @@ refs: destination: /docs/grafana//panels-visualizations/visualizations/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/ + cloudwatch-troubleshooting: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/aws-cloudwatch/troubleshooting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/aws-cloudwatch/troubleshooting/ --- # Amazon CloudWatch data source @@ -119,6 +124,7 @@ The following documents will help you get started working with the CloudWatch da - [CloudWatch query editor](ref:cloudwatch-query-editor) - [Templates and variables](ref:cloudwatch-template-variables) - [Configure AWS authentication](ref:cloudwatch-aws-authentication) +- [Troubleshoot CloudWatch issues](ref:cloudwatch-troubleshooting) ## Import pre-configured dashboards diff --git a/docs/sources/datasources/aws-cloudwatch/configure/index.md b/docs/sources/datasources/aws-cloudwatch/configure/index.md index 7e80433756b..242b3513d47 100644 --- a/docs/sources/datasources/aws-cloudwatch/configure/index.md +++ b/docs/sources/datasources/aws-cloudwatch/configure/index.md @@ -1,11 +1,12 @@ --- aliases: - - ../data-sources/aws-CloudWatch/ - - ../data-sources/aws-CloudWatch/preconfig-CloudWatch-dashboards/ - - ../data-sources/aws-CloudWatch/provision-CloudWatch/ - - CloudWatch/ - - preconfig-CloudWatch-dashboards/ - - provision-CloudWatch/ + - ../../data-sources/aws-cloudwatch/configure/ + - ../../data-sources/aws-cloudwatch/ + - ../../data-sources/aws-cloudwatch/preconfig-cloudwatch-dashboards/ + - ../../data-sources/aws-cloudwatch/provision-cloudwatch/ + - ../cloudwatch/ + - ../preconfig-cloudwatch-dashboards/ + - ../provision-cloudwatch/ description: This document provides configuration instructions for the CloudWatch data source. keywords: - grafana @@ -25,11 +26,6 @@ refs: destination: /docs/grafana//panels-visualizations/visualizations/logs/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//panels-visualizations/visualizations/logs/ - explore: - - pattern: /docs/grafana/ - destination: /docs/grafana//explore/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//explore/ provisioning-data-sources: - pattern: /docs/grafana/ destination: /docs/grafana//administration/provisioning/#data-sources @@ -40,26 +36,16 @@ refs: destination: /docs/grafana//setup-grafana/configure-grafana/#aws - pattern: /docs/grafana-cloud/ destination: /docs/grafana//setup-grafana/configure-grafana/#aws - alerting: - - pattern: /docs/grafana/ - destination: /docs/grafana//alerting/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/alerting-and-irm/alerting/ - build-dashboards: - - pattern: /docs/grafana/ - destination: /docs/grafana//dashboards/build-dashboards/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//dashboards/build-dashboards/ data-source-management: - pattern: /docs/grafana/ destination: /docs/grafana//administration/data-source-management/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//administration/data-source-management/ - CloudWatch-aws-authentication: + cloudwatch-aws-authentication: - pattern: /docs/grafana/ - destination: /docs/grafana//datasources/aws-CloudWatch/aws-authentication/ + destination: /docs/grafana//datasources/aws-cloudwatch/aws-authentication/ - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//datasources/aws-CloudWatch/aws-authentication/ + destination: /docs/grafana//datasources/aws-cloudwatch/aws-authentication/ private-data-source-connect: - pattern: /docs/grafana/ destination: /docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/ @@ -108,7 +94,7 @@ The following are configuration options for the CloudWatch data source. Grafana plugin requests to AWS are made on behalf of an AWS Identity and Access Management (IAM) role or IAM user. The IAM user or IAM role must have the associated policies to perform certain API actions. -For authentication options and configuration details, refer to [AWS authentication](aws-authentication/). +For authentication options and configuration details, refer to [AWS authentication](ref:cloudwatch-aws-authentication). | Setting | Description | | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -153,7 +139,7 @@ You must use both an access key ID and a secret access key to authenticate. Grafana automatically creates a link to a trace in X-Ray data source if logs contain the `@xrayTraceId` field. To use this feature, you must already have an X-Ray data source configured. For details, see the [X-Ray data source docs](/grafana/plugins/grafana-X-Ray-datasource/). To view the X-Ray link, select the log row in either the Explore view or dashboard [Logs panel](ref:logs) to view the log details section. -To log the `@xrayTraceId`, refer to the [AWS X-Ray documentation](https://docs.amazonaws.cn/en_us/xray/latest/devguide/xray-services.html). To provide the field to Grafana, your log queries must also contain the `@xrayTraceId` field, for example by using the query `fields @message, @xrayTraceId`. +To log the `@xrayTraceId`, refer to the [AWS X-Ray documentation](https://docs.aws.amazon.com/xray/latest/devguide/xray-services.html). To provide the field to Grafana, your log queries must also contain the `@xrayTraceId` field, for example by using the query `fields @message, @xrayTraceId`. **Private data source connect** - _Only for Grafana Cloud users._ @@ -172,7 +158,7 @@ To troubleshoot issues while setting up the CloudWatch data source, check the `/ ### IAM policy examples To read CloudWatch metrics and EC2 tags, instances, regions, and alarms, you must grant Grafana permissions via IAM. -You can attach these permissions to the IAM role or IAM user you configured in [AWS authentication](aws-authentication/). +You can attach these permissions to the IAM role or IAM user you configured in [AWS authentication](ref:cloudwatch-aws-authentication). **Metrics-only permissions:** @@ -323,7 +309,7 @@ You can attach these permissions to the IAM role or IAM user you configured in [ Cross-account observability lets you retrieve metrics and logs across different accounts in a single region, but you can't query EC2 Instance Attributes across accounts because those come from the EC2 API and not the CloudWatch API. {{< /admonition >}} -For more information on configuring authentication, refer to [Configure AWS authentication](ref:CloudWatch-aws-authentication). +For more information on configuring authentication, refer to [Configure AWS authentication](ref:cloudwatch-aws-authentication). ### CloudWatch Logs data protection diff --git a/docs/sources/datasources/aws-cloudwatch/query-editor/index.md b/docs/sources/datasources/aws-cloudwatch/query-editor/index.md index 9bc7ab64047..9288a750742 100644 --- a/docs/sources/datasources/aws-cloudwatch/query-editor/index.md +++ b/docs/sources/datasources/aws-cloudwatch/query-editor/index.md @@ -34,11 +34,6 @@ refs: destination: /docs/grafana//panels-visualizations/query-transform-data/#navigate-the-query-tab - pattern: /docs/grafana-cloud/ destination: /docs/grafana//panels-visualizations/query-transform-data/#navigate-the-query-tab - explore: - - pattern: /docs/grafana/ - destination: /docs/grafana//explore/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//explore/ alerting: - pattern: /docs/grafana/ destination: /docs/grafana//alerting/ @@ -183,7 +178,7 @@ If you use the expression field to reference another query, such as `queryA * 2` When you select `Builder` mode within the Metric search editor, a new Account field is displayed. Use the `Account` field to specify which of the linked monitoring accounts to target for the given query. By default, the `All` option is specified, which will target all linked accounts. While in `Code` mode, you can specify any math expression. If the Monitoring account badge displays in the query editor header, all `SEARCH` expressions entered in this field will be cross-account by default and can query metrics from linked accounts. Note that while queries run cross-account, the autocomplete feature currently doesn't fetch cross-account resources, so you'll need to manually specify resource names when writing cross-account queries. -You can limit the search to one or a set of accounts, as documented in the [AWS documentation](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html). +You can limit the search to one or a set of accounts, as documented in the [AWS documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html). ### Period macro @@ -198,7 +193,7 @@ The link provided is valid for any account but displays the expected metrics onl {{< figure src="/media/docs/cloudwatch/cloudwatch-deep-link-v12.1.png" caption="CloudWatch deep linking" >}} -This feature is not available for metrics based on [metric math expressions](#metric-math-expressions). +This feature is not available for metrics based on [metric math expressions](#use-metric-math-expressions). ### Use Metric Insights syntax @@ -319,9 +314,9 @@ The CloudWatch plugin monitors and troubleshoots applications that span multiple To enable cross-account observability, complete the following steps: -1. Go to the [Amazon CloudWatch documentation](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html) and follow the instructions for enabling cross-account observability. +1. Go to the [Amazon CloudWatch documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html) and follow the instructions for enabling cross-account observability. -1. Add [two API actions](https://grafana.com//docs/grafana/latest/datasources/aws-cloudwatch/configure/#cross-account-observability-permissions) to the IAM policy attached to the role/user running the plugin. +1. Add [two API actions](https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/configure/#cross-account-observability-permissions) to the IAM policy attached to the role/user running the plugin. Cross-account querying is available in the plugin through the **Logs**, **Metric search**, and **Metric Insights** modes. After you have configured it, you'll see a **Monitoring account** badge in the query editor header. diff --git a/docs/sources/datasources/aws-cloudwatch/troubleshooting/index.md b/docs/sources/datasources/aws-cloudwatch/troubleshooting/index.md new file mode 100644 index 00000000000..77ce4106bf8 --- /dev/null +++ b/docs/sources/datasources/aws-cloudwatch/troubleshooting/index.md @@ -0,0 +1,519 @@ +--- +aliases: + - ../../data-sources/aws-cloudwatch/troubleshooting/ +description: Troubleshooting guide for the Amazon CloudWatch data source in Grafana +keywords: + - grafana + - cloudwatch + - aws + - troubleshooting + - errors + - authentication + - query +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Troubleshooting +title: Troubleshoot Amazon CloudWatch data source issues +weight: 500 +refs: + configure-cloudwatch: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/aws-cloudwatch/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/aws-cloudwatch/configure/ + cloudwatch-aws-authentication: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/aws-cloudwatch/aws-authentication/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/aws-cloudwatch/aws-authentication/ + cloudwatch-template-variables: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/aws-cloudwatch/template-variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/aws-cloudwatch/template-variables/ + cloudwatch-query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/aws-cloudwatch/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/aws-cloudwatch/query-editor/ + private-data-source-connect: + - pattern: /docs/grafana/ + destination: /docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/ +--- + +# Troubleshoot Amazon CloudWatch data source issues + +This document provides solutions to common issues you may encounter when configuring or using the Amazon CloudWatch data source. For configuration instructions, refer to [Configure CloudWatch](ref:configure-cloudwatch). + +{{< admonition type="note" >}} +The data source health check validates both metrics and logs permissions. If your IAM policy only grants access to one of these (for example, metrics-only or logs-only), the health check displays a red status. However, the service you have permissions for is still usable—you can query metrics or logs based on whichever permissions are configured. +{{< /admonition >}} + +## Authentication errors + +These errors occur when AWS credentials are invalid, missing, or don't have the required permissions. + +### "Access Denied" or "Not authorized to perform this operation" + +**Symptoms:** + +- Save & test fails with "Access Denied" +- Queries return authorization errors +- Namespaces, metrics, or dimensions don't load + +**Possible causes and solutions:** + +| Cause | Solution | +| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| IAM policy missing required permissions | Attach the appropriate IAM policy to your user or role. For metrics, you need `cloudwatch:ListMetrics`, `cloudwatch:GetMetricData`, and related permissions. For logs, you need `logs:DescribeLogGroups`, `logs:StartQuery`, `logs:GetQueryResults`, and related permissions. Refer to [Configure CloudWatch](ref:configure-cloudwatch) for complete policy examples. | +| Incorrect access key or secret key | Verify the credentials in the AWS Console under **IAM** > **Users** > your user > **Security credentials**. Generate new credentials if necessary. | +| Credentials have expired | For temporary credentials, generate new ones. For access keys, verify they haven't been deactivated or deleted. | +| Wrong AWS region | Verify the default region in the data source configuration matches where your resources are located. | +| Assume Role ARN is incorrect | Verify the role ARN format: `arn:aws:iam:::role/`. Check that the role exists in the AWS Console. | + +### "Unable to assume role" + +**Symptoms:** + +- Authentication fails when using Assume Role ARN +- Error message references STS or AssumeRole + +**Solutions:** + +1. Verify the trust relationship on the IAM role allows the Grafana credentials to assume it. +1. Check the trust policy includes the correct principal (the user or role running Grafana). +1. If using an external ID, ensure it matches exactly in both the role's trust policy and the Grafana data source configuration. +1. Verify the base credentials have the `sts:AssumeRole` permission. +1. Check that the role ARN is correct and the role exists. + +**Example trust policy:** + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam:::user/" + }, + "Action": "sts:AssumeRole", + "Condition": { + "StringEquals": { + "sts:ExternalId": "" + } + } + } + ] +} +``` + +### AWS SDK Default authentication not working + +**Symptoms:** + +- Data source test fails when using AWS SDK Default +- Works locally but fails in production + +**Solutions:** + +1. Verify AWS credentials are configured in the environment where Grafana runs. +1. Check for credentials in the default locations: + - Environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`) + - Shared credentials file (`~/.aws/credentials`) + - EC2 instance metadata (if running on EC2) + - ECS task role (if running in ECS) + - EKS service account (if running in EKS) +1. Ensure the Grafana process has permission to read the credentials file. +1. For EKS with IRSA, set the pod's security context to allow user 472 (grafana) to access the projected token. Refer to [AWS authentication](ref:cloudwatch-aws-authentication) for details. + +### Credentials file not found + +**Symptoms:** + +- Error indicates credentials file cannot be read +- Authentication fails with "Credentials file" option + +**Solutions:** + +1. Create the credentials file at `~/.aws/credentials` for the user running the `grafana-server` service. +1. Verify the file has correct permissions (`0644`). +1. If the file exists but isn't working, move it to `/usr/share/grafana/` and set permissions to `0644`. +1. Ensure the profile name in the data source configuration matches a profile in the credentials file. + +## Connection errors + +These errors occur when Grafana cannot reach AWS CloudWatch endpoints. + +### "Request timed out" or connection failures + +**Symptoms:** + +- Data source test times out +- Queries fail with timeout errors +- Intermittent connection issues + +**Solutions:** + +1. Verify network connectivity from the Grafana server to AWS endpoints. +1. Check firewall rules allow outbound HTTPS (port 443) to AWS services. +1. If using a VPC, ensure proper NAT gateway or VPC endpoint configuration. +1. For Grafana Cloud connecting to private resources, configure [Private data source connect](ref:private-data-source-connect). +1. Check if the default region is correct—incorrect regions may cause longer timeouts. +1. Increase the timeout settings if queries involve large data volumes. + +### Custom endpoint configuration issues + +**Symptoms:** + +- Connection fails when using a custom endpoint +- Endpoint URL rejected + +**Solutions:** + +1. Verify the endpoint URL format is correct. +1. Ensure the endpoint is accessible from the Grafana server. +1. Check that the endpoint supports the required AWS APIs. +1. For VPC endpoints, verify the endpoint policy allows the required actions. + +## CloudWatch Metrics query errors + +These errors occur when querying CloudWatch Metrics. + +### "No data" or empty results + +**Symptoms:** + +- Query executes without error but returns no data +- Charts show "No data" message + +**Possible causes and solutions:** + +| Cause | Solution | +| ------------------------------- | ---------------------------------------------------------------------------------------------------------- | +| Time range doesn't contain data | Expand the dashboard time range. CloudWatch metrics have different retention periods based on resolution. | +| Wrong namespace or metric name | Verify the namespace (for example, `AWS/EC2`) and metric name (for example, `CPUUtilization`) are correct. | +| Incorrect dimensions | Ensure dimension names and values match your AWS resources exactly. | +| Match Exact enabled incorrectly | When Match Exact is enabled, all dimensions must be specified. Try disabling it to see if metrics appear. | +| Period too large | Reduce the period setting or set it to "auto" to ensure data points are returned for your time range. | +| Custom metrics not configured | Add custom metric namespaces in the data source configuration under **Namespaces of Custom Metrics**. | + +### "Metric not found" or metrics don't appear in drop-down + +**Symptoms:** + +- Expected metrics don't appear in the query editor +- Metric drop-down is empty for a namespace + +**Solutions:** + +1. Verify the metric exists in the selected region. +1. For custom metrics, add the namespace to **Namespaces of Custom Metrics** in the data source configuration. +1. Check that the IAM policy includes `cloudwatch:ListMetrics` permission. +1. CloudWatch limits `ListMetrics` to 500 results per page. To retrieve more metrics, increase the `list_metrics_page_limit` setting in the [Grafana configuration file](https://grafana.com/docs/grafana/latest/datasources/aws-cloudwatch/configure/#configure-the-data-source-with-grafanaini). +1. Use the Query Inspector to verify the API request and response. + +### Dimension values not loading + +**Symptoms:** + +- Dimension value drop-down doesn't populate +- Wildcard searches return no results + +**Solutions:** + +1. Verify the IAM policy includes `cloudwatch:ListMetrics` permission. +1. Check that the namespace and metric are selected before dimension values can load. +1. For EC2 dimensions, ensure `ec2:DescribeTags` and `ec2:DescribeInstances` permissions are granted. +1. Dimension values require existing metrics—if no metrics match, no values appear. + +### "Too many data points" or API throttling + +**Symptoms:** + +- Queries fail with throttling errors +- Performance degrades with multiple panels + +**Solutions:** + +1. Increase the period setting to reduce the number of data points. +1. Reduce the time range of your queries. +1. Use fewer dimensions or wildcard queries per panel. +1. Request a quota increase for `GetMetricData` requests per second in the [AWS Service Quotas console](https://console.aws.amazon.com/servicequotas/). +1. Enable query caching in Grafana to reduce API calls. + +### Metric math expression errors + +**Symptoms:** + +- Expression returns errors +- Referenced metrics not found + +**Solutions:** + +1. Verify each referenced metric has a unique ID set. +1. Check that metric IDs start with a lowercase letter and contain only letters, numbers, and underscores. +1. Ensure all referenced metrics are in the same query. +1. Verify the expression syntax follows [AWS Metric Math](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html) documentation. +1. Metric math expressions can't be used with Grafana alerting if they reference other query rows. + +## CloudWatch Logs query errors + +These errors occur when querying CloudWatch Logs. + +### "Query failed" or logs don't appear + +**Symptoms:** + +- Log queries return errors +- No log data is displayed + +**Solutions:** + +1. Verify log group names are correct and exist in the selected region. +1. Check the IAM policy includes `logs:StartQuery`, `logs:GetQueryResults`, and `logs:DescribeLogGroups` permissions. +1. Ensure the time range contains log data. +1. Verify the query syntax is valid. For CloudWatch Logs Insights QL, test the query in the AWS Console. +1. Select the correct query language (Logs Insights QL, OpenSearch PPL, or OpenSearch SQL) based on your query syntax. + +### Log query timeout + +**Symptoms:** + +- Query runs for a long time then fails +- Error mentions timeout + +**Solutions:** + +1. Increase the **Query timeout result** setting in the data source configuration (default is 30 minutes). +1. Narrow the time range to reduce the amount of data scanned. +1. Add filters to your query to limit results. +1. Break complex queries into smaller, more focused queries. +1. For alerting, the timeout defined in the [Grafana configuration file](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#unified_alerting) takes precedence. + +### Log groups not appearing in selector + +**Symptoms:** + +- Log group selector is empty +- Can't find expected log groups + +**Solutions:** + +1. Verify the IAM policy includes `logs:DescribeLogGroups` permission. +1. Check that log groups exist in the selected region. +1. For cross-account observability, ensure proper IAM permissions for `oam:ListSinks` and `oam:ListAttachedLinks`. +1. Use prefix search to filter log groups if you have many groups. +1. Verify the selected account (for cross-account) contains the expected log groups. + +### OpenSearch SQL query errors + +**Symptoms:** + +- OpenSearch SQL queries fail +- Syntax errors with SQL queries + +**Solutions:** + +1. Specify the log group identifier or ARN in the `FROM` clause: + + ```sql + SELECT * FROM `log_group_name` WHERE `@message` LIKE '%error%' + ``` + +1. For multiple log groups, use the `logGroups` function: + + ```sql + SELECT * FROM `logGroups(logGroupIdentifier: ['LogGroup1', 'LogGroup2'])` + ``` + +1. Amazon CloudWatch supports only a subset of OpenSearch SQL commands. Refer to the [CloudWatch Logs documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_Languages.html) for supported syntax. + +## Template variable errors + +These errors occur when using template variables with the CloudWatch data source. + +### Variables return no values + +**Symptoms:** + +- Variable drop-down is empty +- Dashboard fails to load with variable errors + +**Solutions:** + +1. Verify the data source connection is working. +1. Check that the IAM policy includes permissions for the variable query type: + - **Regions:** No additional permissions needed. + - **Namespaces:** No additional permissions needed. + - **Metrics:** Requires `cloudwatch:ListMetrics`. + - **Dimension Values:** Requires `cloudwatch:ListMetrics`. + - **EC2 Instance Attributes:** Requires `ec2:DescribeInstances`. + - **EBS Volume IDs:** Requires `ec2:DescribeVolumes`. + - **Resource ARNs:** Requires `tag:GetResources`. + - **Log Groups:** Requires `logs:DescribeLogGroups`. +1. For dependent variables, ensure parent variables have valid selections. +1. Verify the region is set correctly (use "default" for the data source's default region). + +For more information on template variables, refer to [CloudWatch template variables](ref:cloudwatch-template-variables). + +### Multi-value template variables cause query failures + +**Symptoms:** + +- Queries fail when selecting multiple dimension values +- Error about search expression limits + +**Solutions:** + +1. Search expressions are limited to 1,024 characters. Reduce the number of selected values. +1. Use the asterisk (`*`) wildcard instead of selecting "All" to query all metrics for a dimension. +1. Multi-valued template variables are only supported for dimension values—not for Region, Namespace, or Metric Name. + +## Cross-account observability errors + +These errors occur when using CloudWatch cross-account observability features. + +### Cross-account queries fail + +**Symptoms:** + +- Can't query metrics or logs from linked accounts +- Monitoring account badge doesn't appear + +**Solutions:** + +1. Verify cross-account observability is configured in the AWS CloudWatch console. +1. Add the required IAM permissions: + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Action": ["oam:ListSinks", "oam:ListAttachedLinks"], + "Effect": "Allow", + "Resource": "*" + } + ] + } + ``` + +1. Check that the monitoring account and source accounts are properly linked in AWS. +1. Cross-account observability works within a single region—verify all accounts are in the same region. +1. EC2 Instance Attributes can't be queried across accounts because they use the EC2 API, not the CloudWatch API. + +## Quota and pricing issues + +These issues relate to AWS service quotas and cost management. + +### API throttling errors + +**Symptoms:** + +- "Rate exceeded" errors +- Dashboard panels intermittently fail to load + +**Solutions:** + +1. Reduce the frequency of dashboard refreshes. +1. Increase the period setting to reduce `GetMetricData` requests. +1. Enable query caching in Grafana (available in Grafana Enterprise and Grafana Cloud). +1. Request a quota increase in the [AWS Service Quotas console](https://console.aws.amazon.com/servicequotas/). +1. Consider consolidating similar queries using metric math. + +### Unexpectedly high CloudWatch costs + +**Symptoms:** + +- AWS CloudWatch costs are higher than expected +- Frequent API calls from Grafana + +**Solutions:** + +1. The `GetMetricData` API doesn't qualify for the CloudWatch API free tier. +1. Reduce dashboard auto-refresh frequency. +1. Increase the period setting to reduce data points returned. +1. Use query caching to reduce repeated API calls. +1. Review variable query settings—set variable refresh to "On dashboard load" instead of "On time range change." +1. Avoid using wildcards in dimensions when possible, as they generate search expressions with multiple API calls. + +## Other common issues + +These issues don't produce specific error messages but are commonly encountered. + +### Custom metrics don't appear + +**Symptoms:** + +- Custom metrics from applications or agents don't show in the namespace drop-down +- Only standard AWS namespaces are visible + +**Solutions:** + +1. Add your custom metric namespace to the **Namespaces of Custom Metrics** field in the data source configuration. +1. Separate multiple namespaces with commas (for example, `CWAgent,CustomNamespace`). +1. Verify custom metrics have been published to CloudWatch in the selected region. + +### Pre-configured dashboards not working + +**Symptoms:** + +- Imported dashboards show no data +- Dashboard variables don't load + +**Solutions:** + +1. Verify the data source name in the dashboard matches your CloudWatch data source. +1. Check that the dashboard's AWS region setting matches where your resources are located. +1. Ensure the IAM policy grants access to the required services (EC2, Lambda, RDS, etc.). +1. Verify resources exist and are emitting metrics in the selected region. + +### X-Ray trace links not appearing + +**Symptoms:** + +- Log entries don't show X-Ray trace links +- `@xrayTraceId` field not appearing + +**Solutions:** + +1. Verify an X-Ray data source is configured and linked in the CloudWatch data source settings. +1. Ensure your logs contain the `@xrayTraceId` field. +1. Update log queries to include `@xrayTraceId` in the fields, for example: `fields @message, @xrayTraceId`. +1. Configure your application to log X-Ray trace IDs. Refer to the [AWS X-Ray documentation](https://docs.aws.amazon.com/xray/latest/devguide/xray-services.html). + +## Enable debug logging + +To capture detailed error information for troubleshooting: + +1. Set the Grafana log level to `debug` in the configuration file: + + ```ini + [log] + level = debug + ``` + +1. Review logs in `/var/log/grafana/grafana.log` (or your configured log location). +1. Look for CloudWatch-specific entries that include request and response details. +1. Reset the log level to `info` after troubleshooting to avoid excessive log volume. + +## Get additional help + +If you've tried the solutions above and still encounter issues: + +1. Check the [Grafana community forums](https://community.grafana.com/) for similar issues. +1. Review the [CloudWatch plugin GitHub issues](https://github.com/grafana/grafana/issues) for known bugs. +1. Consult the [AWS CloudWatch documentation](https://docs.aws.amazon.com/cloudwatch/) for service-specific guidance. +1. Contact Grafana Support if you're an Enterprise, Cloud Pro, or Cloud Contracted user. +1. When reporting issues, include: + - Grafana version + - AWS region + - Error messages (redact sensitive information) + - Steps to reproduce + - Query configuration (redact credentials and account IDs) diff --git a/docs/sources/datasources/azure-monitor/_index.md b/docs/sources/datasources/azure-monitor/_index.md index 90452f4cc52..d66b19efdff 100644 --- a/docs/sources/datasources/azure-monitor/_index.md +++ b/docs/sources/datasources/azure-monitor/_index.md @@ -3,7 +3,6 @@ aliases: - ../data-sources/azure-monitor/ - ../features/datasources/azuremonitor/ - azuremonitor/ - - azuremonitor/deprecated-application-insights/ description: Guide for using Azure Monitor in Grafana keywords: - grafana @@ -23,6 +22,7 @@ labels: menuTitle: Azure Monitor title: Azure Monitor data source weight: 300 +last_reviewed: 2025-12-04 refs: configure-grafana-feature-toggles: - pattern: /docs/grafana/ @@ -49,6 +49,11 @@ refs: destination: /docs/grafana//dashboards/build-dashboards/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//dashboards/build-dashboards/ + transform-data: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/query-transform-data/transform-data/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//panels-visualizations/query-transform-data/transform-data/ configure-grafana-azure: - pattern: /docs/grafana/ destination: /docs/grafana//setup-grafana/configure-grafana/#azure @@ -63,295 +68,98 @@ refs: - pattern: /docs/grafana/ destination: /docs/grafana//setup-grafana/configure-access/configure-authentication/azuread/#enable-azure-ad-oauth-in-grafana - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//setup-grafana/configure-access/configure-authentication/azuread/#enable-azure-ad-oauth-in-grafana + destination: /docs/grafana//setup-grafana/configure-security/configure-authentication/azuread/#enable-azure-ad-oauth-in-grafana + configure-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + query-editor-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ + template-variables-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/template-variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/template-variables/ + alerting-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/alerting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/alerting/ + troubleshooting-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/troubleshooting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/troubleshooting/ + annotations-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/annotations/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/annotations/ --- # Azure Monitor data source -Grafana ships with built-in support for Azure Monitor, the Azure service to maximize the availability and performance of applications and services in the Azure Cloud. -This topic explains configuring and querying specific to the Azure Monitor data source. +The Azure Monitor data source plugin allows you to query and visualize data from Azure Monitor, the Azure service to maximize the availability and performance of applications and services in the Azure Cloud. -For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref:data-source-management). -Only users with the organization administrator role can add data sources. +## Supported Azure clouds -Once you've added the Azure Monitor data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). +The Azure Monitor data source supports the following Azure cloud environments: -The Azure Monitor data source supports visualizing data from four Azure services: +- **Azure** - Azure public cloud (default) +- **Azure US Government** - Azure Government cloud +- **Azure China** - Azure China cloud operated by 21Vianet -- **Azure Monitor Metrics:** Collect numeric data from resources in your Azure account. -- **Azure Monitor Logs:** Collect log and performance data from your Azure account, and query using the Kusto Query Language (KQL). -- **Azure Resource Graph:** Query your Azure resources across subscriptions. -- **Azure Monitor Application Insights:** Collect trace logging data and other application performance metrics. +## Supported Azure services -## Configure the data source +The Azure Monitor data source supports the following Azure services: -**To access the data source configuration page:** +| Service | Description | +| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| **Azure Monitor Metrics** | Collect numeric data from resources in your Azure account. Supports dimensions, aggregations, and time grain configuration. | +| **Azure Monitor Logs** | Collect log and performance data from your Azure account using the Kusto Query Language (KQL). | +| **Azure Resource Graph** | Query your Azure resources across subscriptions using KQL. Useful for inventory, compliance, and resource management. | +| **Application Insights Traces** | Collect distributed trace data and correlate requests across your application components. | -1. Click **Connections** in the left-side menu. -1. Under Your connections, click **Data sources**. -1. Enter `Azure Monitor` in the search bar. -1. Click **Azure Monitor**. +## Get started - The **Settings** tab of the data source is displayed. +The following documents will help you get started with the Azure Monitor data source: -### Configure Azure Active Directory (AD) authentication +- [Configure the Azure Monitor data source](ref:configure-azure-monitor) - Set up authentication and connect to Azure +- [Azure Monitor query editor](ref:query-editor-azure-monitor) - Create and edit queries for Metrics, Logs, Traces, and Resource Graph +- [Template variables](ref:template-variables-azure-monitor) - Create dynamic dashboards with Azure Monitor variables +- [Alerting](ref:alerting-azure-monitor) - Create alert rules using Azure Monitor data +- [Troubleshooting](ref:troubleshooting-azure-monitor) - Solve common configuration and query errors -You must create an app registration and service principal in Azure AD to authenticate the data source. -For configuration details, refer to the [Azure documentation for service principals](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#get-tenant-and-app-id-values-for-signing-in). +## Additional features -The app registration you create must have the `Reader` role assigned on the subscription. -For more information, refer to [Azure documentation for role assignments](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal?tabs=current). +After you have configured the Azure Monitor data source, you can: -If you host Grafana in Azure, such as in App Service or Azure Virtual Machines, you can configure the Azure Monitor data source to use Managed Identity for secure authentication without entering credentials into Grafana. -For details, refer to [Configuring using Managed Identity](#configuring-using-managed-identity). +- Add [Annotations](ref:annotations-azure-monitor) to overlay Azure log events on your graphs. +- Configure and use [Template variables](ref:template-variables-azure-monitor) for dynamic dashboards. +- Add [Transformations](ref:transform-data) to manipulate query results. +- Set up [Alerting](ref:alerting-azure-monitor) and recording rules using Metrics, Logs, Traces, and Resource Graph queries. +- Use [Explore](ref:explore) to investigate your Azure data without building a dashboard. -You can configure the Azure Monitor data source to use Workload Identity for secure authentication without entering credentials into Grafana if you host Grafana in a Kubernetes environment, such as AKS, and require access to Azure resources. -For details, refer to [Configuring using Workload Identity](#configuring-using-workload-identity). +## Pre-built dashboards -| Name | Description | -| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Authentication** | Enables Managed Identity. Selecting Managed Identity hides many of the other fields. For details, see [Configuring using Managed Identity](#configuring-using-managed-identity). | -| **Azure Cloud** | Sets the national cloud for your Azure account. For most users, this is the default "Azure". For details, see the [Azure documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/authentication-national-cloud). | -| **Directory (tenant) ID** | Sets the directory/tenant ID for the Azure AD app registration to use for authentication. For details, see the [Azure tenant and app ID docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#get-tenant-and-app-id-values-for-signing-in). | -| **Application (client) ID** | Sets the application/client ID for the Azure AD app registration to use for authentication. | -| **Client secret** | Sets the application client secret for the Azure AD app registration to use for authentication. For details, see the [Azure application secret docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret). | -| **Default subscription** | _(Optional)_ Sets a default subscription for template variables to use. | -| **Enable Basic Logs** | Allows this data source to execute queries against [Basic Logs tables](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/basic-logs-query?tabs=portal-1) in supported Log Analytics Workspaces. These queries may incur additional costs. | +The Azure Monitor plugin includes the following pre-built dashboards: -### Provision the data source +- **Azure Monitor Overview** - Displays key metrics across your Azure subscriptions and resources. +- **Azure Storage Account** - Shows storage account metrics including availability, latency, and transactions. -You can define and configure the data source in YAML files as part of Grafana's provisioning system. -For more information about provisioning, and for available configuration options, refer to [Provisioning Grafana](ref:provisioning-data-sources). +To import a pre-built dashboard: -#### Provisioning examples +1. Go to **Connections** > **Data sources**. +1. Select your Azure Monitor data source. +1. Click the **Dashboards** tab. +1. Click **Import** next to the dashboard you want to use. -**Azure AD App Registration (client secret):** +## Related resources -```yaml -apiVersion: 1 # config file version - -datasources: - - name: Azure Monitor - type: grafana-azure-monitor-datasource - access: proxy - jsonData: - azureAuthType: clientsecret - cloudName: azuremonitor # See table below - tenantId: - clientId: - subscriptionId: # Optional, default subscription - secureJsonData: - clientSecret: - version: 1 -``` - -**Managed Identity:** - -```yaml -apiVersion: 1 # config file version - -datasources: - - name: Azure Monitor - type: grafana-azure-monitor-datasource - access: proxy - jsonData: - azureAuthType: msi - subscriptionId: # Optional, default subscription - version: 1 -``` - -**Workload Identity:** - -```yaml -apiVersion: 1 # config file version - -datasources: - - name: Azure Monitor - type: grafana-azure-monitor-datasource - access: proxy - jsonData: - azureAuthType: workloadidentity - subscriptionId: # Optional, default subscription - version: 1 -``` - -**Current User:** - -{{< admonition type="note" >}} -The `oauthPassThru` property is required for current user authentication to function. -Additionally, `disableGrafanaCache` is necessary to prevent the data source returning cached responses for resources users don't have access to. -{{< /admonition >}} - -```yaml -apiVersion: 1 # config file version - -datasources: - - name: Azure Monitor - type: grafana-azure-monitor-datasource - access: proxy - jsonData: - azureAuthType: currentuser - oauthPassThru: true - disableGrafanaCache: true - subscriptionId: # Optional, default subscription - version: 1 -``` - -#### Supported cloud names - -| Azure Cloud | `cloudName` Value | -| ------------------------------------ | -------------------------- | -| **Microsoft Azure public cloud** | `azuremonitor` (_Default_) | -| **Microsoft Chinese national cloud** | `chinaazuremonitor` | -| **US Government cloud** | `govazuremonitor` | - -{{< admonition type="note" >}} -Cloud names for current user authentication differ to the `cloudName` values in the preceding table. -The public cloud name is `AzureCloud`, the Chinese national cloud name is `AzureChinaCloud`, and the US Government cloud name is `AzureUSGovernment`. -{{< /admonition >}} - -### Configure Managed Identity - -{{< admonition type="note" >}} -Managed Identity is available only in [Azure Managed Grafana](https://azure.microsoft.com/en-us/products/managed-grafana) or Grafana OSS/Enterprise when deployed in Azure. It is not available in Grafana Cloud. -{{< /admonition >}} - -You can use managed identity to configure Azure Monitor in Grafana if you host Grafana in Azure (such as an App Service or with Azure Virtual Machines) and have managed identity enabled on your VM. -This lets you securely authenticate data sources without manually configuring credentials via Azure AD App Registrations. -For details on Azure managed identities, refer to the [Azure documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview). - -**To enable managed identity for Grafana:** - -1. Set the `managed_identity_enabled` flag in the `[azure]` section of the [Grafana server configuration](ref:configure-grafana-azure). - - ```ini - [azure] - managed_identity_enabled = true - ``` - -2. In the Azure Monitor data source configuration, set **Authentication** to **Managed Identity**. - - This hides the directory ID, application ID, and client secret fields, and the data source uses managed identity to authenticate to Azure Monitor Metrics and Logs, and Azure Resource Graph. - - {{< figure src="/media/docs/grafana/data-sources/screenshot-managed-identity-2.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor screenshot showing Managed Identity authentication" >}} - -3. You can set the `managed_identity_client_id` field in the `[azure]` section of the [Grafana server configuration](ref:configure-grafana-azure) to allow a user-assigned managed identity to be used instead of the default system-assigned identity. - -```ini -[azure] -managed_identity_enabled = true -managed_identity_client_id = USER_ASSIGNED_IDENTITY_CLIENT_ID -``` - -### Configure Workload Identity - -You can use workload identity to configure Azure Monitor in Grafana if you host Grafana in a Kubernetes environment, such as AKS, in conjunction with managed identities. -This lets you securely authenticate data sources without manually configuring credentials via Azure AD App Registrations. -For details on workload identity, refer to the [Azure workload identity documentation](https://azure.github.io/azure-workload-identity/docs/). - -**To enable workload identity for Grafana:** - -1. Set the `workload_identity_enabled` flag in the `[azure]` section of the [Grafana server configuration](ref:configure-grafana-azure). - - ```ini - [azure] - workload_identity_enabled = true - ``` - -2. In the Azure Monitor data source configuration, set **Authentication** to **Workload Identity**. - - This hides the directory ID, application ID, and client secret fields, and the data source uses workload identity to authenticate to Azure Monitor Metrics and Logs, and Azure Resource Graph. - - {{< figure src="/media/docs/grafana/data-sources/screenshot-workload-identity.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor screenshot showing Workload Identity authentication" >}} - -3. There are additional configuration variables that can control the authentication method.`workload_identity_tenant_id` represents the Azure AD tenant that contains the managed identity, `workload_identity_client_id` represents the client ID of the managed identity if it differs from the default client ID, `workload_identity_token_file` represents the path to the token file. Refer to the [documentation](https://azure.github.io/azure-workload-identity/docs/) for more information on what values these variables should use, if any. - - ```ini - [azure] - workload_identity_enabled = true - workload_identity_tenant_id = IDENTITY_TENANT_ID - workload_identity_client_id = IDENTITY_CLIENT_ID - workload_identity_token_file = TOKEN_FILE_PATH - ``` - -### Configure Current User authentication - -{{< admonition type="note" >}} -Current user authentication is an [experimental feature](/docs/release-life-cycle). Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Contact Grafana Support to enable this feature in Grafana Cloud. Aspects of Grafana may not work as expected when using this authentication method. -{{< /admonition >}} - -If your Grafana instance is configured with Azure Entra (formerly Active Directory) authentication for login, this authentication method can be used to forward the currently logged in user's credentials to the data source. The users credentials will then be used when requesting data from the data source. For details on how to configure your Grafana instance using Azure Entra refer to the [documentation](ref:configure-grafana-azure-auth). - -{{< admonition type="note" >}} -Additional configuration is required to ensure that the App Registration used to login a user via Azure provides an access token with the permissions required by the data source. - -The App Registration must be configured to issue both **Access Tokens** and **ID Tokens**. - -1. In the Azure Portal, open the App Registration that requires configuration. -2. Select **Authentication** in the side menu. -3. Under **Implicit grant and hybrid flows** check both the **Access tokens** and **ID tokens** boxes. -4. Save the changes to ensure the App Registration is updated. - -The App Registration must also be configured with additional **API Permissions** to provide authenticated users with access to the APIs utilised by the data source. - -1. In the Azure Portal, open the App Registration that requires configuration. -1. Select **API Permissions** in the side menu. -1. Ensure the `openid`, `profile`, `email`, and `offline_access` permissions are present under the **Microsoft Graph** section. If not, they must be added. -1. Select **Add a permission** and choose the following permissions. They must be added individually. Refer to the [Azure documentation](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-configure-app-access-web-apis) for more information. - - Select **Azure Service Management** > **Delegated permissions** > `user_impersonation` > **Add permissions** - - Select **APIs my organization uses** > Search for **Log Analytics API** and select it > **Delegated permissions** > `Date.Read` > **Add permissions** - -Once all permissions have been added, the Azure authentication section in Grafana must be updated. The `scopes` section must be updated to include the `.default` scope to ensure that a token with access to all APIs declared on the App Registration is requested by Grafana. Once updated the scopes value should equal: `.default openid email profile`. -{{< /admonition >}} - -This method of authentication doesn't inherently support all backend functionality as a user's credentials won't be in scope. -Affected functionality includes alerting, reporting, and recorded queries. -In order to support backend queries when using a data source configured with current user authentication, you can configure service credentials. -Also, note that query and resource caching is disabled by default for data sources using current user authentication. - -{{< admonition type="note" >}} -To configure fallback service credentials the [feature toggle](ref:configure-grafana-feature-toggles) `idForwarding` must be set to `true` and `user_identity_fallback_credentials_enabled` must be enabled in the [Azure configuration section](ref:configure-grafana-azure) (enabled by default when `user_identity_enabled` is set to `true`). -{{< /admonition >}} - -Permissions for fallback credentials may need to be broad to appropriately support backend functionality. -For example, an alerting query created by a user is dependent on their permissions. -If a user tries to create an alert for a resource that the fallback credentials can't access, the alert will fail. - -**To enable current user authentication for Grafana:** - -1. Set the `user_identity_enabled` flag in the `[azure]` section of the [Grafana server configuration](ref:configure-grafana-azure). - By default this will also enable fallback service credentials. - If you want to disable service credentials at the instance level set `user_identity_fallback_credentials_enabled` to false. - - ```ini - [azure] - user_identity_enabled = true - ``` - -1. In the Azure Monitor data source configuration, set **Authentication** to **Current User**. - If fallback service credentials are enabled at the instance level, an additional configuration section is visible that you can use to enable or disable using service credentials for this data source. - {{< figure src="/media/docs/grafana/data-sources/screenshot-current-user.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor screenshot showing Current User authentication" >}} - -1. If you want backend functionality to work with this data source, enable service credentials and configure the data source using the most applicable credentials for your circumstances. - -## Query the data source - -The Azure Monitor data source can query data from Azure Monitor Metrics and Logs, the Azure Resource Graph, and Application Insights Traces. Each source has its own specialized query editor. - -For details, see the [query editor documentation](query-editor/). - -## Use template variables - -Instead of hard-coding details such as server, application, and sensor names in metric queries, you can use variables. -Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. -Grafana refers to such variables as template variables. - -For details, see the [template variables documentation](template-variables/). - -## Application Insights and Insights Analytics (removed) - -Until Grafana v8.0, you could query the same Azure Application Insights data using Application Insights and Insights Analytics. - -These queries were deprecated in Grafana v7.5. In Grafana v8.0, Application Insights and Insights Analytics were made read-only in favor of querying this data through Metrics and Logs. These query methods were completely removed in Grafana v9.0. - -If you're upgrading from a Grafana version prior to v9.0 and relied on Application Insights and Analytics queries, refer to the [Grafana v9.0 documentation](/docs/grafana/v9.0/datasources/azuremonitor/deprecated-application-insights/) for help migrating these queries to Metrics and Logs queries. +- [Azure Monitor documentation](https://docs.microsoft.com/en-us/azure/azure-monitor/) +- [Kusto Query Language (KQL) reference](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/) +- [Grafana community forum](https://community.grafana.com/) diff --git a/docs/sources/datasources/azure-monitor/alerting/index.md b/docs/sources/datasources/azure-monitor/alerting/index.md new file mode 100644 index 00000000000..860c1d343a4 --- /dev/null +++ b/docs/sources/datasources/azure-monitor/alerting/index.md @@ -0,0 +1,262 @@ +--- +aliases: + - ../../data-sources/azure-monitor/alerting/ +description: Set up alerts using Azure Monitor data in Grafana +keywords: + - grafana + - azure + - monitor + - alerting + - alerts + - metrics + - logs +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Alerting +title: Azure Monitor alerting +weight: 500 +refs: + alerting: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//alerting/ + alerting-fundamentals: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//alerting/fundamentals/ + create-alert-rule: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/alerting-rules/create-grafana-managed-rule/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//alerting/alerting-rules/create-grafana-managed-rule/ + grafana-managed-recording-rules: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/alerting-rules/create-recording-rules/create-grafana-managed-recording-rules/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//alerting/alerting-rules/create-recording-rules/create-grafana-managed-recording-rules/ + configure-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ + troubleshoot: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/troubleshooting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/troubleshooting/ +--- + +# Azure Monitor alerting + +The Azure Monitor data source supports [Grafana Alerting](ref:alerting) and [Grafana-managed recording rules](ref:grafana-managed-recording-rules), allowing you to create alert rules based on Azure metrics, logs, traces, and resource data. You can monitor your Azure environment and receive notifications when specific conditions are met. + +## Before you begin + +- Ensure you have the appropriate permissions to create alert rules in Grafana. +- Verify your Azure Monitor data source is configured and working correctly. +- Familiarize yourself with [Grafana Alerting concepts](ref:alerting-fundamentals). +- **Important**: Verify your data source uses a supported authentication method. Refer to [Authentication requirements](#authentication-requirements). + +## Supported query types for alerting + +All Azure Monitor query types support alerting and recording rules: + +| Query type | Use case | Notes | +| -------------------- | -------------------------------------------------- | -------------------------------------------------------- | +| Metrics | Threshold-based alerts on Azure resource metrics | Best suited for alerting; returns time-series data | +| Logs | Alert on log patterns, error counts, or thresholds | Use KQL to aggregate data into numeric values | +| Azure Resource Graph | Alert on resource state or configuration changes | Use count aggregations to return numeric data | +| Traces | Alert on trace data and application performance | Use aggregations to return numeric values for evaluation | + +{{< admonition type="note" >}} +Alert queries must return numeric data that Grafana can evaluate against a threshold. Queries that return only text or non-numeric data cannot be used directly for alerting. +{{< /admonition >}} + +## Authentication requirements + +Alerting and recording rules run as background processes without a user context. This means they require service-level authentication and don't work with all authentication methods. + +| Authentication method | Supported | +| -------------------------------- | ------------------------------------- | +| App Registration (client secret) | ✓ | +| Managed Identity | ✓ | +| Workload Identity | ✓ | +| Current User | ✓ (with fallback service credentials) | + +{{< admonition type="note" >}} +If you use **Current User** authentication, you must configure **fallback service credentials** for alerting and recording rules to function. User credentials aren't available for background operations, so Grafana uses the fallback credentials instead. Refer to [configure the data source](ref:configure-azure-monitor) for details on setting up fallback credentials. +{{< /admonition >}} + +## Create an alert rule + +To create an alert rule using Azure Monitor data: + +1. Go to **Alerting** > **Alert rules**. +1. Click **New alert rule**. +1. Enter a name for your alert rule. +1. In the **Define query and alert condition** section: + - Select your Azure Monitor data source. + - Configure your query (for example, a Metrics query for CPU usage or a Logs query using KQL). + - Add a **Reduce** expression if your query returns multiple series. + - Add a **Threshold** expression to define the alert condition. +1. Configure the **Set evaluation behavior**: + - Select or create a folder and evaluation group. + - Set the evaluation interval (how often the alert is checked). + - Set the pending period (how long the condition must be true before firing). +1. Add labels and annotations to provide context for notifications. +1. Click **Save rule**. + +For detailed instructions, refer to [Create a Grafana-managed alert rule](ref:create-alert-rule). + +## Example: VM CPU usage alert + +This example creates an alert that fires when virtual machine CPU usage exceeds 80%: + +1. Create a new alert rule. +1. Configure the query: + - **Service**: Metrics + - **Resource**: Select your virtual machine + - **Metric namespace**: `Microsoft.Compute/virtualMachines` + - **Metric**: `Percentage CPU` + - **Aggregation**: `Average` +1. Add expressions: + - **Reduce**: Last (to get the most recent data point) + - **Threshold**: Is above 80 +1. Set evaluation to run every 1 minute with a 5-minute pending period. +1. Save the rule. + +## Example: Error log count alert + +This example alerts when error logs exceed a threshold using a KQL query: + +1. Create a new alert rule. +1. Configure the query: + - **Service**: Logs + - **Resource**: Select your Log Analytics workspace + - **Query**: + ```kusto + AppExceptions + | where TimeGenerated > ago(5m) + | summarize ErrorCount = count() by bin(TimeGenerated, 1m) + ``` +1. Add expressions: + - **Reduce**: Max (to get the highest count in the period) + - **Threshold**: Is above 10 +1. Set evaluation to run every 5 minutes. +1. Save the rule. + +## Example: Resource count alert + +This example alerts when the number of running virtual machines drops below a threshold using Azure Resource Graph: + +1. Create a new alert rule. +1. Configure the query: + - **Service**: Azure Resource Graph + - **Subscriptions**: Select your subscriptions + - **Query**: + + ```kusto + resources + | where type == "microsoft.compute/virtualmachines" + | where properties.extended.instanceView.powerState.displayStatus == "VM running" + | summarize RunningVMs = count() + ``` + +1. Add expressions: + - **Reduce**: Last + - **Threshold**: Is below 3 +1. Set evaluation to run every 5 minutes. +1. Save the rule. + +## Best practices + +Follow these recommendations to create reliable and efficient alerts with Azure Monitor data. + +### Use appropriate query intervals + +- Set the alert evaluation interval to be greater than or equal to the minimum data resolution from Azure Monitor. +- Azure Monitor Metrics typically have 1-minute granularity at minimum. +- Avoid very short intervals (less than 1 minute) as they may cause evaluation timeouts or miss data points. + +### Reduce multiple series + +When your Azure Monitor query returns multiple time series (for example, CPU usage across multiple VMs), use the **Reduce** expression to aggregate them: + +- **Last**: Use the most recent value +- **Mean**: Average across all series +- **Max/Min**: Use the highest or lowest value +- **Sum**: Total across all series + +### Optimize Log Analytics queries + +For Logs queries used in alerting: + +- Use `summarize` to aggregate data into numeric values. +- Include appropriate time filters using `ago()` or `TimeGenerated`. +- Avoid returning large result sets; aggregate data in the query. +- Test queries in Explore before using them in alert rules. + +### Handle no data conditions + +Configure what happens when no data is returned: + +1. In the alert rule, find **Configure no data and error handling**. +1. Choose an appropriate action: + - **No Data**: Keep the alert in its current state + - **Alerting**: Treat no data as an alert condition + - **OK**: Treat no data as a healthy state + +### Test queries before alerting + +Always verify your query returns expected data before creating an alert: + +1. Go to **Explore**. +1. Select your Azure Monitor data source. +1. Run the query you plan to use for alerting. +1. Confirm the data format and values are correct. +1. Verify the query returns numeric data suitable for threshold evaluation. + +## Troubleshooting + +If your Azure Monitor alerts aren't working as expected, use the following sections to diagnose and resolve common issues. + +### Alerts not firing + +- Verify the data source uses a supported authentication method. If using Current User authentication, ensure fallback service credentials are configured. +- Check that the query returns numeric data in Explore. +- Ensure the evaluation interval allows enough time for data to be available. +- Review the alert rule's health and any error messages in the Alerting UI. + +### Authentication errors in alert evaluation + +If you see authentication errors when alerts evaluate: + +- Confirm the data source is configured with App Registration, Managed Identity, Workload Identity, or Current User with fallback service credentials. +- If using App Registration, verify the client secret hasn't expired. +- If using Current User, verify that fallback service credentials are configured and valid. +- Check that the service principal has appropriate permissions on Azure resources. + +### Query timeout errors + +- Simplify complex KQL queries. +- Reduce the time range in Log Analytics queries. +- Add more specific filters to narrow result sets. + +For additional troubleshooting help, refer to [Troubleshoot Azure Monitor](ref:troubleshoot). + +## Additional resources + +- [Grafana Alerting documentation](ref:alerting) +- [Create alert rules](ref:create-alert-rule) +- [Azure Monitor query editor](ref:query-editor) +- [Grafana-managed recording rules](ref:grafana-managed-recording-rules) diff --git a/docs/sources/datasources/azure-monitor/annotations/index.md b/docs/sources/datasources/azure-monitor/annotations/index.md new file mode 100644 index 00000000000..43fbb914a9d --- /dev/null +++ b/docs/sources/datasources/azure-monitor/annotations/index.md @@ -0,0 +1,218 @@ +--- +aliases: + - ../../data-sources/azure-monitor/annotations/ +description: Use annotations with the Azure Monitor data source in Grafana +keywords: + - grafana + - azure + - monitor + - annotations + - events + - logs +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Annotations +title: Azure Monitor annotations +weight: 450 +refs: + annotate-visualizations: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/build-dashboards/annotate-visualizations/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/build-dashboards/annotate-visualizations/ + query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ +--- + +# Azure Monitor annotations + +[Annotations](ref:annotate-visualizations) overlay rich event information on top of graphs. You can use Azure Monitor Log Analytics queries to create annotations that mark important events, deployments, alerts, or other significant occurrences on your dashboards. + +## Before you begin + +- Ensure you have configured the Azure Monitor data source. +- You need access to a Log Analytics workspace containing the data you want to use for annotations. +- Annotations use Log Analytics (KQL) queries only. Metrics, Traces, and Azure Resource Graph queries are not supported for annotations. + +## Create an annotation query + +To add an Azure Monitor annotation to a dashboard: + +1. Open the dashboard where you want to add annotations. +1. Click **Dashboard settings** (gear icon) in the top navigation. +1. Select **Annotations** in the left menu. +1. Click **Add annotation query**. +1. Enter a **Name** for the annotation (e.g., "Azure Activity", "Deployments"). +1. Select your **Azure Monitor** data source. +1. Choose the **Logs** service. +1. Select a **Resource** (Log Analytics workspace or Application Insights resource). +1. Write a KQL query that returns the annotation data. +1. Click **Apply** to save. + +## Query requirements + +Your KQL query should return columns that Grafana can use to create annotations: + +| Column | Required | Description | +| ------------------ | ----------- | ------------------------------------------------------------------------------------------------ | +| `TimeGenerated` | Yes | The timestamp for the annotation. Grafana uses this to position the annotation on the time axis. | +| `Text` | Recommended | The annotation text displayed when you hover over or click the annotation. | +| Additional columns | Optional | Any other columns returned become annotation tags. | + +{{< admonition type="note" >}} +Always include a time filter in your query to limit results to the dashboard's time range. Use the `$__timeFilter()` macro. +{{< /admonition >}} + +## Annotation query examples + +The following examples demonstrate common annotation use cases. + +### Azure Activity Log events + +Display Azure Activity Log events such as resource modifications, deployments, and administrative actions: + +```kusto +AzureActivity +| where $__timeFilter(TimeGenerated) +| where Level == "Error" or Level == "Warning" or CategoryValue == "Administrative" +| project TimeGenerated, Text=OperationNameValue, Level, ResourceGroup, Caller +| order by TimeGenerated desc +| take 100 +``` + +### Deployment events + +Show deployment-related activity: + +```kusto +AzureActivity +| where $__timeFilter(TimeGenerated) +| where OperationNameValue contains "deployments" +| project TimeGenerated, Text=strcat("Deployment: ", OperationNameValue), Status=ActivityStatusValue, ResourceGroup +| order by TimeGenerated desc +``` + +### Application Insights exceptions + +Mark application exceptions as annotations: + +```kusto +AppExceptions +| where $__timeFilter(TimeGenerated) +| project TimeGenerated, Text=strcat(ProblemId, ": ", OuterMessage), SeverityLevel, AppRoleName +| order by TimeGenerated desc +| take 50 +``` + +### Custom events from Application Insights + +Display custom events logged by your application: + +```kusto +AppEvents +| where $__timeFilter(TimeGenerated) +| where Name == "DeploymentStarted" or Name == "DeploymentCompleted" +| project TimeGenerated, Text=Name, AppRoleName +| order by TimeGenerated desc +``` + +### Security alerts + +Show security-related alerts: + +```kusto +SecurityAlert +| where $__timeFilter(TimeGenerated) +| project TimeGenerated, Text=AlertName, Severity=AlertSeverity, Description +| order by TimeGenerated desc +| take 50 +``` + +### Resource health events + +Display resource health status changes: + +```kusto +AzureActivity +| where $__timeFilter(TimeGenerated) +| where CategoryValue == "ResourceHealth" +| project TimeGenerated, Text=OperationNameValue, Status=ActivityStatusValue, ResourceId +| order by TimeGenerated desc +``` + +### VM start and stop events + +Mark virtual machine state changes: + +```kusto +AzureActivity +| where $__timeFilter(TimeGenerated) +| where OperationNameValue has_any ("start", "deallocate", "restart") +| where ResourceProviderValue == "MICROSOFT.COMPUTE" +| project TimeGenerated, Text=OperationNameValue, VM=Resource, Status=ActivityStatusValue +| order by TimeGenerated desc +``` + +### Autoscale events + +Show autoscale operations: + +```kusto +AzureActivity +| where $__timeFilter(TimeGenerated) +| where OperationNameValue contains "autoscale" +| project TimeGenerated, Text=strcat("Autoscale: ", OperationNameValue), Status=ActivityStatusValue, ResourceGroup +| order by TimeGenerated desc +``` + +## Customize annotation appearance + +After creating an annotation query, you can customize its appearance: + +| Setting | Description | +| ------------- | -------------------------------------------------------------------------------------------------------- | +| **Color** | Choose a color for the annotation markers. Use different colors to distinguish between annotation types. | +| **Show in** | Select which panels display the annotations. | +| **Filter by** | Add filters to limit when annotations appear. | + +## Best practices + +Follow these recommendations when creating annotations: + +1. **Limit results**: Always use `take` or `limit` to restrict the number of annotations. Too many annotations can clutter your dashboard and impact performance. + +2. **Use time filters**: Include `$__timeFilter()` to ensure queries only return data within the dashboard's time range. + +3. **Create meaningful text**: Use `strcat()` or `project` to create descriptive annotation text that provides context at a glance. + +4. **Add relevant tags**: Include columns like `ResourceGroup`, `Severity`, or `Status` that become clickable tags for filtering. + +5. **Use descriptive names**: Name your annotations clearly (e.g., "Production Deployments", "Critical Alerts") so dashboard users understand what they represent. + +## Troubleshoot annotations + +If annotations aren't appearing as expected, try the following solutions. + +### Annotations don't appear + +- Verify the query returns data in the selected time range. +- Check that the query includes a `TimeGenerated` column. +- Test the query in the Azure Portal Log Analytics query editor. +- Ensure the annotation is enabled (toggle is on). + +### Too many annotations + +- Add more specific filters to your query. +- Use `take` to limit results. +- Narrow the time range. + +### Annotations appear at wrong times + +- Verify the `TimeGenerated` column contains the correct timestamp. +- Check your dashboard's timezone settings. diff --git a/docs/sources/datasources/azure-monitor/configure/index.md b/docs/sources/datasources/azure-monitor/configure/index.md new file mode 100644 index 00000000000..cef21b08744 --- /dev/null +++ b/docs/sources/datasources/azure-monitor/configure/index.md @@ -0,0 +1,605 @@ +--- +aliases: + - ../../data-sources/azure-monitor/configure/ +description: Guide for configuring the Azure Monitor data source in Grafana. +keywords: + - grafana + - microsoft + - azure + - monitor + - application + - insights + - log + - analytics + - guide +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Configure +title: Configure the Azure Monitor data source +weight: 200 +last_reviewed: 2025-12-04 +refs: + configure-grafana-feature-toggles: + - pattern: /docs/grafana/ + destination: /docs/grafana//setup-grafana/configure-grafana/#feature_toggles + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//setup-grafana/configure-grafana/#feature_toggles + provisioning-data-sources: + - pattern: /docs/grafana/ + destination: /docs/grafana//administration/provisioning/#data-sources + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//administration/provisioning/#data-sources + explore: + - pattern: /docs/grafana/ + destination: /docs/grafana//explore/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//explore/ + configure-grafana-azure-auth: + - pattern: /docs/grafana/ + destination: /docs/grafana//setup-grafana/configure-security/configure-authentication/azuread/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//setup-grafana/configure-security/configure-authentication/azuread/ + build-dashboards: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/build-dashboards/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/build-dashboards/ + configure-grafana-azure: + - pattern: /docs/grafana/ + destination: /docs/grafana//setup-grafana/configure-grafana/#azure + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//setup-grafana/configure-grafana/#azure + data-source-management: + - pattern: /docs/grafana/ + destination: /docs/grafana//administration/data-source-management/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//administration/data-source-management/ + configure-grafana-azure-auth-scopes: + - pattern: /docs/grafana/ + destination: /docs/grafana//setup-grafana/configure-security/configure-authentication/azuread/#enable-azure-ad-oauth-in-grafana + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//setup-grafana/configure-security/configure-authentication/azuread/#enable-azure-ad-oauth-in-grafana + data-sources: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/ + private-data-source-connect: + - pattern: /docs/grafana/ + destination: docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/ + - pattern: /docs/grafana-cloud/ + destination: docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/ + configure-pdc: + - pattern: /docs/grafana/ + destination: /docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-grafana-private-data-source-connect-pdc + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-grafana-private-data-source-connect-pdc +--- + +# Configure the Azure Monitor data source + +This document explains how to configure the Azure Monitor data source and the available configuration options. +For general information about data sources, refer to [Grafana data sources](ref:data-sources) and [Data source management](ref:data-source-management). + +## Before you begin + +Before configuring the Azure Monitor data source, ensure you have the following: + +- **Grafana permissions:** You must have the `Organization administrator` role to configure data sources. + Organization administrators can also [configure the data source via YAML](#provision-the-data-source) with the Grafana provisioning system or [using Terraform](#configure-with-terraform). + +- **Azure prerequisites:** Depending on your chosen authentication method, you may need: + - A Microsoft Entra ID (formerly Azure AD) app registration with a service principal (for App Registration authentication) + - A Managed Identity enabled on your Azure VM or App Service (for Managed Identity authentication) + - Workload identity configured in your Kubernetes cluster (for Workload Identity authentication) + - Microsoft Entra ID authentication configured for Grafana login (for Current User authentication) + +{{< admonition type="note" >}} +**Grafana Cloud users:** Managed Identity and Workload Identity authentication methods are not available in Grafana Cloud because they require Grafana to run on your Azure infrastructure. Use **App Registration** authentication instead. +{{< /admonition >}} + +- **Azure RBAC permissions:** The identity used to authenticate must have the `Reader` role on the Azure subscription containing the resources you want to monitor. + For Log Analytics queries, the identity also needs appropriate permissions on the Log Analytics workspaces to be queried. + Refer to the [Azure documentation for role assignments](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal?tabs=current). + +{{< admonition type="note" >}} +The Azure Monitor data source plugin is built into Grafana. No additional installation is required. +{{< /admonition >}} + +## Add the data source + +To add the Azure Monitor data source: + +1. Click **Connections** in the left-side menu. +1. Click **Add new connection**. +1. Type `Azure Monitor` in the search bar. +1. Select **Azure Monitor**. +1. Click **Add new data source** in the upper right. + +You're taken to the **Settings** tab where you can configure the data source. + +## Choose an authentication method + +The Azure Monitor data source supports four authentication methods. Choose based on where Grafana is hosted and your security requirements: + +| Authentication method | Best for | Requirements | +| --------------------- | ------------------------------------------ | -------------------------------------------------------------- | +| **App Registration** | Any Grafana deployment | Microsoft Entra ID app registration with client secret | +| **Managed Identity** | Grafana hosted in Azure (VMs, App Service) | Managed identity enabled on the Azure resource | +| **Workload Identity** | Grafana in Kubernetes (AKS) | Workload identity federation configured | +| **Current User** | User-level access control | Microsoft Entra ID authentication configured for Grafana login | + +## Configure authentication + +Select one of the following authentication methods and complete the configuration. + +### App Registration + +Use a Microsoft Entra ID app registration (service principal) to authenticate. This method works with any Grafana deployment. + +#### App Registration prerequisites + +1. Create an app registration in Microsoft Entra ID. + Refer to the [Azure documentation for creating a service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#get-tenant-and-app-id-values-for-signing-in). + +1. Create a client secret for the app registration. + Refer to the [Azure documentation for creating a client secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret). + +1. Assign the `Reader` role to the app registration on the subscription or resources you want to monitor. + Refer to the [Azure documentation for role assignments](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal?tabs=current). + +#### App Registration UI configuration + +| Setting | Description | +| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| **Authentication** | Select **App Registration**. | +| **Azure Cloud** | The Azure environment to connect to. Select **Azure** for the public cloud, or choose Azure Government or Azure China for national clouds. | +| **Directory (tenant) ID** | The GUID that identifies your Microsoft Entra ID tenant. | +| **Application (client) ID** | The GUID for the app registration you created. | +| **Client secret** | The secret key for the app registration. Keep this secure and rotate periodically. | +| **Default Subscription** | Click **Load Subscriptions** to populate available subscriptions, then select your default. | + +#### Provision App Registration with YAML + +```yaml +apiVersion: 1 + +datasources: + - name: Azure Monitor + type: grafana-azure-monitor-datasource + access: proxy + jsonData: + azureAuthType: clientsecret + cloudName: azuremonitor # See supported cloud names below + tenantId: + clientId: + subscriptionId: # Optional, default subscription + secureJsonData: + clientSecret: + version: 1 +``` + +### Managed Identity + +Use Azure Managed Identity for secure, credential-free authentication when Grafana is hosted in Azure. + +{{< admonition type="note" >}} +Managed Identity is available in [Azure Managed Grafana](https://azure.microsoft.com/en-us/products/managed-grafana) or self-hosted Grafana deployed in Azure. It is not available in Grafana Cloud. +{{< /admonition >}} + +#### Managed Identity prerequisites + +- Grafana must be hosted in Azure (App Service, Azure VMs, or Azure Managed Grafana). +- Managed identity must be enabled on the Azure resource hosting Grafana. +- The managed identity must have the `Reader` role on the subscription or resources you want to monitor. + +For details on Azure managed identities, refer to the [Azure documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview). + +#### Managed Identity Grafana server configuration + +Enable managed identity in the Grafana server configuration: + +```ini +[azure] +managed_identity_enabled = true +``` + +To use a user-assigned managed identity instead of the system-assigned identity, also set: + +```ini +[azure] +managed_identity_enabled = true +managed_identity_client_id = +``` + +Refer to [Grafana Azure configuration](ref:configure-grafana-azure) for more details. + +#### Managed Identity UI configuration + +| Setting | Description | +| ------------------------ | --------------------------------------------------------------------------------------------------- | +| **Authentication** | Select **Managed Identity**. The directory ID, application ID, and client secret fields are hidden. | +| **Default Subscription** | Click **Load Subscriptions** to populate available subscriptions, then select your default. | + +{{< figure src="/media/docs/grafana/data-sources/screenshot-managed-identity-2.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor data source configured with Managed Identity" >}} + +#### Provision Managed Identity with YAML + +```yaml +apiVersion: 1 + +datasources: + - name: Azure Monitor + type: grafana-azure-monitor-datasource + access: proxy + jsonData: + azureAuthType: msi + subscriptionId: # Optional, default subscription + version: 1 +``` + +### Workload Identity + +Use Azure Workload Identity for secure authentication in Kubernetes environments like AKS. + +#### Workload Identity prerequisites + +- Grafana must be running in a Kubernetes environment with workload identity federation configured. +- The workload identity must have the `Reader` role on the subscription or resources you want to monitor. + +For details, refer to the [Azure workload identity documentation](https://azure.github.io/azure-workload-identity/docs/). + +#### Workload Identity Grafana server configuration + +Enable workload identity in the Grafana server configuration: + +```ini +[azure] +workload_identity_enabled = true +``` + +Optional configuration variables: + +```ini +[azure] +workload_identity_enabled = true +workload_identity_tenant_id = # Microsoft Entra ID tenant containing the managed identity +workload_identity_client_id = # Client ID if different from default +workload_identity_token_file = # Path to the token file +``` + +Refer to [Grafana Azure configuration](ref:configure-grafana-azure) and the [Azure workload identity documentation](https://azure.github.io/azure-workload-identity/docs/) for more details. + +#### Workload Identity UI configuration + +| Setting | Description | +| ------------------------ | ---------------------------------------------------------------------------------------------------- | +| **Authentication** | Select **Workload Identity**. The directory ID, application ID, and client secret fields are hidden. | +| **Default Subscription** | Click **Load Subscriptions** to populate available subscriptions, then select your default. | + +{{< figure src="/media/docs/grafana/data-sources/screenshot-workload-identity.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor data source configured with Workload Identity" >}} + +#### Provision Workload Identity with YAML + +```yaml +apiVersion: 1 + +datasources: + - name: Azure Monitor + type: grafana-azure-monitor-datasource + access: proxy + jsonData: + azureAuthType: workloadidentity + subscriptionId: # Optional, default subscription + version: 1 +``` + +### Current User + +Forward the logged-in Grafana user's Azure credentials to the data source for user-level access control. + +{{< admonition type="warning" >}} +Current User authentication is an [experimental feature](/docs/release-life-cycle/). Engineering and on-call support is not available. Documentation is limited. No SLA is provided. Contact Grafana Support to enable this feature in Grafana Cloud. +{{< /admonition >}} + +#### Current User prerequisites + +Your Grafana instance must be configured with Microsoft Entra ID authentication. Refer to the [Microsoft Entra ID authentication documentation](ref:configure-grafana-azure-auth). + +#### Configure your Azure App Registration + +The App Registration used for Grafana login requires additional configuration: + +**Enable token issuance:** + +1. In the Azure Portal, open your App Registration. +1. Select **Authentication** in the side menu. +1. Under **Implicit grant and hybrid flows**, check both **Access tokens** and **ID tokens**. +1. Save your changes. + +**Add API permissions:** + +1. In the Azure Portal, open your App Registration. +1. Select **API Permissions** in the side menu. +1. Ensure these permissions are present under **Microsoft Graph**: `openid`, `profile`, `email`, and `offline_access`. +1. Add the following permissions: + - **Azure Service Management** > **Delegated permissions** > `user_impersonation` + - **APIs my organization uses** > Search for **Log Analytics API** > **Delegated permissions** > `Data.Read` + +Refer to the [Azure documentation](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-configure-app-access-web-apis) for more information. + +**Update Grafana scopes:** + +Update the `scopes` section in your Grafana Azure authentication configuration to include the `.default` scope: + +``` +.default openid email profile +``` + +#### Current User Grafana server configuration + +Enable current user authentication in the Grafana server configuration: + +```ini +[azure] +user_identity_enabled = true +``` + +By default, this also enables fallback service credentials. To disable fallback credentials at the instance level: + +```ini +[azure] +user_identity_enabled = true +user_identity_fallback_credentials_enabled = false +``` + +{{< admonition type="note" >}} +To use fallback service credentials, the [feature toggle](ref:configure-grafana-feature-toggles) `idForwarding` must be set to `true`. +{{< /admonition >}} + +#### Limitations and fallback credentials + +Current User authentication doesn't support backend functionality like alerting, reporting, and recorded queries because user credentials aren't available for background operations. + +To support these features, configure **fallback service credentials**. When enabled, Grafana uses the fallback credentials for backend operations. Note that operations using fallback credentials are limited to the permissions of those credentials, not the user's permissions. + +{{< admonition type="note" >}} +Query and resource caching is disabled by default for data sources using Current User authentication. +{{< /admonition >}} + +#### Current User UI configuration + +| Setting | Description | +| -------------------------------- | ------------------------------------------------------------------------------------------- | +| **Authentication** | Select **Current User**. | +| **Default Subscription** | Click **Load Subscriptions** to populate available subscriptions, then select your default. | +| **Fallback Service Credentials** | Enable and configure credentials for backend features like alerting. | + +{{< figure src="/media/docs/grafana/data-sources/screenshot-current-user.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor data source configured with Current User authentication" >}} + +#### Provision Current User with YAML + +{{< admonition type="note" >}} +The `oauthPassThru` property is required for Current User authentication. The `disableGrafanaCache` property prevents returning cached responses for resources users don't have access to. +{{< /admonition >}} + +```yaml +apiVersion: 1 + +datasources: + - name: Azure Monitor + type: grafana-azure-monitor-datasource + access: proxy + jsonData: + azureAuthType: currentuser + oauthPassThru: true + disableGrafanaCache: true + subscriptionId: # Optional, default subscription + version: 1 +``` + +## Additional configuration options + +These settings apply to all authentication methods. + +### General settings + +| Setting | Description | +| ----------- | ------------------------------------------------------------------------------- | +| **Name** | The data source name used in panels and queries. Example: `azure-monitor-prod`. | +| **Default** | Toggle to make this the default data source for new panels. | + +### Enable Basic Logs + +Toggle **Enable Basic Logs** to allow queries against [Basic Logs tables](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/basic-logs-query?tabs=portal-1) in supported Log Analytics Workspaces. + +{{< admonition type="note" >}} +Querying Basic Logs tables incurs additional costs on a per-query basis. +{{< /admonition >}} + +### Private data source connect (Grafana Cloud only) + +If you're using Grafana Cloud and need to connect to Azure resources in a private network, use Private Data Source Connect (PDC). + +1. Click the **Private data source connect** dropdown to select your PDC configuration. +1. Click **Manage private data source connect** to view your PDC connection details. + +For more information, refer to [Private data source connect](ref:private-data-source-connect) and [Configure PDC](ref:configure-pdc). + +## Supported cloud names + +When provisioning the data source, use the following `cloudName` values: + +| Azure Cloud | `cloudName` value | +| -------------------------------- | ------------------------ | +| Microsoft Azure public cloud | `azuremonitor` (default) | +| Microsoft Chinese national cloud | `chinaazuremonitor` | +| US Government cloud | `govazuremonitor` | + +{{< admonition type="note" >}} +For Current User authentication, the cloud names differ: use `AzureCloud` for public cloud, `AzureChinaCloud` for the Chinese national cloud, and `AzureUSGovernment` for the US Government cloud. +{{< /admonition >}} + +## Verify the connection + +After configuring the data source, click **Save & test**. A successful connection displays a message confirming that the credentials are valid and have access to the configured default subscription. + +If the test fails, verify: + +- Your credentials are correct (tenant ID, client ID, client secret) +- The identity has the required Azure RBAC permissions +- For Managed Identity or Workload Identity, that the Grafana server configuration is correct +- Network connectivity to Azure endpoints + +## Provision the data source + +You can define and configure the Azure Monitor data source in YAML files as part of the Grafana provisioning system. +For more information about provisioning, refer to [Provisioning Grafana](ref:provisioning-data-sources). + +### Provision quick reference + +| Authentication method | `azureAuthType` value | Required fields | +| --------------------- | --------------------- | -------------------------------------------------- | +| App Registration | `clientsecret` | `tenantId`, `clientId`, `clientSecret` | +| Managed Identity | `msi` | None (uses VM identity) | +| Workload Identity | `workloadidentity` | None (uses pod identity) | +| Current User | `currentuser` | `oauthPassThru: true`, `disableGrafanaCache: true` | + +All methods support the optional `subscriptionId` field to set a default subscription. + +For complete YAML examples, see the [authentication method sections](#configure-authentication) above. + +## Configure with Terraform + +You can configure the Azure Monitor data source using the [Grafana Terraform provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs). This approach enables infrastructure-as-code workflows and version control for your Grafana configuration. + +### Terraform prerequisites + +- [Terraform](https://www.terraform.io/downloads) installed +- Grafana Terraform provider configured with appropriate credentials +- For Grafana Cloud: A [Cloud Access Policy token](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/access-policies/) with data source permissions + +### Provider configuration + +Configure the Grafana provider to connect to your Grafana instance: + +```hcl +terraform { + required_providers { + grafana = { + source = "grafana/grafana" + version = ">= 2.0.0" + } + } +} + +# For Grafana Cloud +provider "grafana" { + url = "" + auth = "" +} + +# For self-hosted Grafana +# provider "grafana" { +# url = "http://localhost:3000" +# auth = "" +# } +``` + +### Terraform examples + +The following examples show how to configure the Azure Monitor data source for each authentication method. + +**App Registration (client secret):** + +```hcl +resource "grafana_data_source" "azure_monitor" { + type = "grafana-azure-monitor-datasource" + name = "Azure Monitor" + + json_data_encoded = jsonencode({ + azureAuthType = "clientsecret" + cloudName = "azuremonitor" + tenantId = "" + clientId = "" + subscriptionId = "" + }) + + secure_json_data_encoded = jsonencode({ + clientSecret = "" + }) +} +``` + +**Managed Identity:** + +```hcl +resource "grafana_data_source" "azure_monitor" { + type = "grafana-azure-monitor-datasource" + name = "Azure Monitor" + + json_data_encoded = jsonencode({ + azureAuthType = "msi" + subscriptionId = "" + }) +} +``` + +**Workload Identity:** + +```hcl +resource "grafana_data_source" "azure_monitor" { + type = "grafana-azure-monitor-datasource" + name = "Azure Monitor" + + json_data_encoded = jsonencode({ + azureAuthType = "workloadidentity" + subscriptionId = "" + }) +} +``` + +**Current User:** + +```hcl +resource "grafana_data_source" "azure_monitor" { + type = "grafana-azure-monitor-datasource" + name = "Azure Monitor" + + json_data_encoded = jsonencode({ + azureAuthType = "currentuser" + oauthPassThru = true + disableGrafanaCache = true + subscriptionId = "" + }) +} +``` + +**With Basic Logs enabled:** + +Add `enableBasicLogs = true` to any of the above configurations: + +```hcl +resource "grafana_data_source" "azure_monitor" { + type = "grafana-azure-monitor-datasource" + name = "Azure Monitor" + + json_data_encoded = jsonencode({ + azureAuthType = "clientsecret" + cloudName = "azuremonitor" + tenantId = "" + clientId = "" + subscriptionId = "" + enableBasicLogs = true + }) + + secure_json_data_encoded = jsonencode({ + clientSecret = "" + }) +} +``` + +For more information about the Grafana Terraform provider, refer to the [provider documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs) and the [grafana_data_source resource](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source). diff --git a/docs/sources/datasources/azure-monitor/query-editor/index.md b/docs/sources/datasources/azure-monitor/query-editor/index.md index 6415be1281c..a8c763d9280 100644 --- a/docs/sources/datasources/azure-monitor/query-editor/index.md +++ b/docs/sources/datasources/azure-monitor/query-editor/index.md @@ -21,6 +21,7 @@ labels: menuTitle: Query editor title: Azure Monitor query editor weight: 300 +last_reviewed: 2025-12-04 refs: query-transform-data-query-options: - pattern: /docs/grafana/ @@ -32,30 +33,85 @@ refs: destination: /docs/grafana//panels-visualizations/query-transform-data/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//panels-visualizations/query-transform-data/ + configure-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + explore: + - pattern: /docs/grafana/ + destination: /docs/grafana//explore/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//explore/ + troubleshoot-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/troubleshooting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/troubleshooting/ + configure-grafana-feature-toggles: + - pattern: /docs/grafana/ + destination: /docs/grafana//setup-grafana/configure-grafana/feature-toggles/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//setup-grafana/configure-grafana/feature-toggles/ + template-variables: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/template-variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/template-variables/ + alerting-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/alerting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/alerting/ + annotations-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/annotations/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/annotations/ --- # Azure Monitor query editor -This topic explains querying specific to the Azure Monitor data source. -For general documentation on querying data sources in Grafana, see [Query and transform data](ref:query-transform-data). +Grafana provides a query editor for the Azure Monitor data source, which is located on the [Explore page](ref:explore). You can also access the Azure Monitor query editor from a dashboard panel. Click the menu in the upper right of the panel and select **Edit**. -## Choose a query editing mode +This document explains querying specific to the Azure Monitor data source. +For general documentation on querying data sources in Grafana, refer to [Query and transform data](ref:query-transform-data). -The Azure Monitor data source's query editor has three modes depending on which Azure service you want to query: +The Azure Monitor data source can query data from Azure Monitor Metrics and Logs, the Azure Resource Graph, and Application Insights Traces. Each source has its own specialized query editor. + +## Before you begin + +- Ensure you have [configured the Azure Monitor data source](ref:configure-azure-monitor). +- Verify your credentials have appropriate permissions for the resources you want to query. + +## Key concepts + +If you're new to Azure Monitor, here are some key terms used throughout this documentation: + +| Term | Description | +| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **KQL (Kusto Query Language)** | The query language used for Azure Monitor Logs and Azure Resource Graph. KQL uses a pipe-based syntax similar to Unix commands and is optimized for read-only data exploration. If you know SQL, the [SQL to Kusto cheat sheet](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/sqlcheatsheet) can help you get started. | +| **Log Analytics workspace** | An Azure resource that collects and stores log data from your Azure resources, applications, and services. You query this data using KQL. | +| **Application Insights** | Azure's application performance monitoring (APM) service. It collects telemetry data like requests, exceptions, and traces from your applications. | +| **Metrics vs. Logs** | **Metrics** are lightweight numeric values collected at regular intervals (e.g., CPU percentage). **Logs** are detailed records of events with varying schemas (e.g., request logs, error messages). Metrics use a visual query builder; Logs require KQL. | + +## Choose a query editor mode + +The Azure Monitor data source's query editor has four modes depending on which Azure service you want to query: - **Metrics** for [Azure Monitor Metrics](#query-azure-monitor-metrics) - **Logs** for [Azure Monitor Logs](#query-azure-monitor-logs) -- [**Azure Resource Graph**](#query-azure-resource-graph) - **Traces** for [Application Insights Traces](#query-application-insights-traces) +- **Azure Resource Graph** for [Azure Resource Graph](#query-azure-resource-graph) ## Query Azure Monitor Metrics -Azure Monitor Metrics collects numeric data from [supported resources](https://docs.microsoft.com/en-us/azure/azure-monitor/monitor-reference), and you can query them to investigate your resources' health and usage and maximise availability and performance. +Azure Monitor Metrics collects numeric data from [supported resources](https://docs.microsoft.com/en-us/azure/azure-monitor/monitor-reference), and you can query them to investigate your resources' health and usage and maximize availability and performance. Monitor Metrics use a lightweight format that stores only numeric data in a specific structure and supports near real-time scenarios, making it useful for fast detection of issues. In contrast, Azure Monitor Logs can store a variety of data types, each with their own structure. -{{< figure src="/static/img/docs/azure-monitor/query-editor-metrics.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Logs Metrics sample query visualizing CPU percentage over time" >}} +{{< figure src="/static/img/docs/azure-monitor/query-editor-metrics.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor Metrics sample query visualizing CPU percentage over time" >}} ### Create a Metrics query @@ -85,7 +141,7 @@ Optionally, you can apply further aggregations or filter by dimensions. The available options change depending on what is relevant to the selected metric. -You can also augment queries by using [template variables](../template-variables/). +You can also augment queries by using [template variables](ref:template-variables). ### Format legend aliases @@ -109,7 +165,7 @@ For example: | `{{ dimensionname }}` | _(Legacy for backward compatibility)_ Replaced with the name of the first dimension. | | `{{ dimensionvalue }}` | _(Legacy for backward compatibility)_ Replaced with the value of the first dimension. | -### Filter using dimensions +### Filter with dimensions Some metrics also have dimensions, which associate additional metadata. Dimensions are represented as key-value pairs assigned to each value of a metric. @@ -121,7 +177,7 @@ For more information on multi-dimensional metrics, refer to the [Azure Monitor d ## Query Azure Monitor Logs -Azure Monitor Logs collects and organises log and performance data from [supported resources](https://docs.microsoft.com/en-us/azure/azure-monitor/monitor-reference), and makes many sources of data available to query together with the [Kusto Query Language (KQL)](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/). +Azure Monitor Logs collects and organizes log and performance data from [supported resources](https://docs.microsoft.com/en-us/azure/azure-monitor/monitor-reference), and makes many sources of data available to query together with the [Kusto Query Language (KQL)](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/). While Azure Monitor Metrics stores only simplified numerical data, Logs can store different data types, each with their own structure. You can also perform complex analysis of Logs data by using KQL. @@ -130,6 +186,32 @@ The Azure Monitor data source also supports querying of [Basic Logs](https://lea {{< figure src="/static/img/docs/azure-monitor/query-editor-logs.png" max-width="800px" class="docs-image--no-shadow" caption="Azure Monitor Logs sample query comparing successful requests to failed requests" >}} +### Logs query builder (public preview) + +{{< admonition type="note" >}} +The Logs query builder is a [public preview feature](/docs/release-life-cycle/). It may not be enabled in all Grafana environments. +{{< /admonition >}} + +The Logs query builder provides a visual interface for building Azure Monitor Logs queries without writing KQL. This is helpful if you're new to KQL or want to quickly build simple queries. + +**To enable the Logs query builder:** + +1. Enable the `azureMonitorLogsBuilderEditor` [feature toggle](ref:configure-grafana-feature-toggles) in your Grafana configuration. +1. Restart Grafana for the change to take effect. + +**To switch between Builder and Code modes:** + +When the feature is enabled, a **Builder / Code** toggle appears in the Logs query editor: + +- **Builder**: Use the visual interface to select tables, columns, filters, and aggregations. The builder generates the KQL query for you. +- **Code**: Write KQL queries directly. Use this mode for complex queries that require full KQL capabilities. + +New queries default to Builder mode. Existing queries that were created with raw KQL remain in Code mode. + +{{< admonition type="note" >}} +You can switch from Builder to Code mode at any time to view or edit the generated KQL. However, switching from Code to Builder mode may not preserve complex queries that can't be represented in the builder interface. +{{< /admonition >}} + ### Create a Logs query **To create a Logs query:** @@ -140,13 +222,13 @@ The Azure Monitor data source also supports querying of [Basic Logs](https://lea Alternatively, you can dynamically query all resources under a single resource group or subscription. {{< admonition type="note" >}} - If a timespan is specified in the query, the overlap of the timespan between the query and the dashboard will be used as the query timespan. See the [API documentation for + If a time span is specified in the query, the overlap between the query time span and the dashboard time range will be used. See the [API documentation for details.](https://learn.microsoft.com/en-us/rest/api/loganalytics/dataaccess/query/get?tabs=HTTP#uri-parameters) {{< /admonition >}} 1. Enter your KQL query. -You can also augment queries by using [template variables](../template-variables/). +You can also augment queries by using [template variables](ref:template-variables). **To create a Basic Logs query:** @@ -161,7 +243,7 @@ You can also augment queries by using [template variables](../template-variables {{< /admonition >}} 1. Enter your KQL query. -You can also augment queries by using [template variables](https://grafana.com/docs/grafana//datasources/azure-monitor/template-variables/). +You can also augment queries by using [template variables](ref:template-variables). ### Logs query examples @@ -174,24 +256,28 @@ The Azure documentation includes resources to help you learn KQL: - [Tutorial: Use Kusto queries in Azure Monitor](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/tutorial?pivots=azuremonitor) - [SQL to Kusto cheat sheet](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/sqlcheatsheet) -> **Time-range:** The time-range that will be used for the query can be modified via the time-range switch. Selecting `Query` will only make use of time-ranges specified within the query. -> Specifying `Dashboard` will only make use of the Grafana time-range. -> If there are no time-ranges specified within the query, the default Log Analytics time-range will apply. -> For more details on this change, refer to the [Azure Monitor Logs API documentation](https://learn.microsoft.com/en-us/rest/api/loganalytics/dataaccess/query/get?tabs=HTTP#uri-parameters). -> If the `Intersection` option was previously chosen it will be migrated by default to `Dashboard`. +{{< admonition type="note" >}} +**Time-range:** The time-range used for the query can be modified via the time-range switch: -This example query returns a virtual machine's CPU performance, averaged over 5ms time grains: +- Selecting **Query** uses only time-ranges specified within the query. +- Selecting **Dashboard** uses only the Grafana dashboard time-range. +- If no time-range is specified in the query, the default Log Analytics time-range applies. + +For more details, refer to the [Azure Monitor Logs API documentation](https://learn.microsoft.com/en-us/rest/api/loganalytics/dataaccess/query/get?tabs=HTTP#uri-parameters). If you previously used the `Intersection` option, it has been migrated to `Dashboard`. +{{< /admonition >}} + +This example query returns a virtual machine's CPU performance, averaged over 5-minute time grains: ```kusto Perf -# $__timeFilter is a special Grafana macro that filters the results to the time span of the dashboard +// $__timeFilter is a special Grafana macro that filters the results to the time span of the dashboard | where $__timeFilter(TimeGenerated) | where CounterName == "% Processor Time" | summarize avg(CounterValue) by bin(TimeGenerated, 5m), Computer | order by TimeGenerated asc ``` -Use time series queries for values that change over time, usually for graph visualisations such as the Time series panel. +Use time series queries for values that change over time, usually for graph visualizations such as the Time series panel. Each query should return at least a datetime column and numeric value column. The result must also be sorted in ascending order by the datetime column. @@ -357,21 +443,33 @@ Application Insights stores trace data in an underlying Log Analytics workspace This query type only supports Application Insights resources. {{< /admonition >}} -Running a query of this kind will return all trace data within the timespan specified by the panel/dashboard. +1. (Optional) Specify an **Operation ID** value to filter traces. +1. (Optional) Specify **event types** to filter by. +1. (Optional) Specify **event properties** to filter by. +1. (Optional) Change the **Result format** to switch between tabular format and trace format. -Optionally, you can apply further filtering or select a specific Operation ID to query. The result format can also be switched between a tabular format or the trace format which will return the data in a format that can be used with the Trace visualization. + {{< admonition type="note" >}} + Selecting the trace format filters events to only the `trace` type. Use this format with the Trace visualization. + {{< /admonition >}} -{{< admonition type="note" >}} -Selecting the trace format will filter events with the `trace` type. -{{< /admonition >}} +Running a query returns all trace data within the time span specified by the panel or dashboard time range. -1. Specify an Operation ID value. -1. Specify event types to filter by. -1. Specify event properties to filter by. +You can also augment queries by using [template variables](ref:template-variables). -You can also augment queries by using [template variables](../template-variables/). +## Use queries for alerting and recording rules -## Working with large Azure resource data sets +All Azure Monitor query types (Metrics, Logs, Azure Resource Graph, and Traces) can be used with Grafana Alerting and recording rules. + +For detailed information about creating alert rules, supported query types, authentication requirements, and examples, refer to [Azure Monitor alerting](ref:alerting-azure-monitor). + +## Work with large Azure resource datasets If a request exceeds the [maximum allowed value of records](https://docs.microsoft.com/en-us/azure/governance/resource-graph/concepts/work-with-data#paging-results), the result is paginated and only the first page of results are returned. You can use filters to reduce the amount of records returned under that value. + +## Next steps + +- [Use template variables](../template-variables/) to create dynamic, reusable dashboards +- [Add annotations](ref:annotations-azure-monitor) to overlay events on your graphs +- [Set up alerting](ref:alerting-azure-monitor) to create alert rules based on Azure Monitor data +- [Troubleshoot](ref:troubleshoot-azure-monitor) common query and configuration issues diff --git a/docs/sources/datasources/azure-monitor/template-variables/index.md b/docs/sources/datasources/azure-monitor/template-variables/index.md index 1db472a4251..3cedadef9b5 100644 --- a/docs/sources/datasources/azure-monitor/template-variables/index.md +++ b/docs/sources/datasources/azure-monitor/template-variables/index.md @@ -23,6 +23,7 @@ labels: menuTitle: Template variables title: Azure Monitor template variables weight: 400 +last_reviewed: 2025-12-04 refs: variables: - pattern: /docs/grafana/ @@ -34,6 +35,11 @@ refs: destination: /docs/grafana//dashboards/variables/add-template-variables/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//dashboards/variables/add-template-variables/ + configure-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/configure/ --- # Azure Monitor template variables @@ -42,58 +48,173 @@ Instead of hard-coding details such as resource group or resource name values in This helps you create more interactive, dynamic, and reusable dashboards. Grafana refers to such variables as template variables. -For an introduction to templating and template variables, refer to the [Templating](ref:variables) and [Add and manage variables](ref:add-template-variables) documentation. +For an introduction to templating and template variables, refer to the [Templating](ref:variables) and [Add and manage variables](ref:add-template-variables). -## Use query variables +## Before you begin -You can specify these Azure Monitor data source queries in the Variable edit view's **Query Type** field. +- Ensure you have [configured the Azure Monitor data source](ref:configure-azure-monitor). +- If you want template variables to auto-populate subscriptions, set a **Default Subscription** in the data source configuration. -| Name | Description | -| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| **Subscriptions** | Returns subscriptions. | -| **Resource Groups** | Returns resource groups for a specified subscription. Supports multi-value. | -| **Namespaces** | Returns metric namespaces for the specified subscription. If a resource group is provided, only the namespaces within that group are returned. | -| **Regions** | Returns regions for the specified subscription | -| **Resource Names** | Returns a list of resource names for a specified subscription, resource group and namespace. Supports multi-value. | -| **Metric Names** | Returns a list of metric names for a resource. | -| **Workspaces** | Returns a list of workspaces for the specified subscription. | -| **Logs** | Use a KQL query to return values. | -| **Custom Namespaces** | Returns metric namespaces for the specified resource. | -| **Custom Metric Names** | Returns a list of custom metric names for the specified resource. | +## Create a template variable + +To create a template variable for Azure Monitor: + +1. Open the dashboard where you want to add the variable. +1. Click **Dashboard settings** (gear icon) in the top navigation. +1. Select **Variables** in the left menu. +1. Click **Add variable**. +1. Enter a **Name** for your variable (e.g., `subscription`, `resourceGroup`, `resource`). +1. In the **Type** dropdown, select **Query**. +1. In the **Data source** dropdown, select your Azure Monitor data source. +1. In the **Query Type** dropdown, select the appropriate query type (see [Available query types](#available-query-types)). +1. Configure any additional fields required by the selected query type. +1. Click **Run query** to preview the variable values. +1. Configure display options such as **Multi-value** or **Include All option** as needed. +1. Click **Apply** to save the variable. + +## Available query types + +The Azure Monitor data source provides the following query types for template variables: + +| Query type | Description | +| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| **Subscriptions** | Returns a list of Azure subscriptions accessible to the configured credentials. | +| **Resource Groups** | Returns resource groups for a specified subscription. Supports multi-value selection. | +| **Namespaces** | Returns metric namespaces for the specified subscription. If a resource group is specified, returns only namespaces within that group. | +| **Regions** | Returns Azure regions available for the specified subscription. | +| **Resource Names** | Returns resource names for a specified subscription, resource group, and namespace. Supports multi-value selection. | +| **Metric Names** | Returns available metric names for a specified resource. | +| **Workspaces** | Returns Log Analytics workspaces for the specified subscription. | +| **Logs** | Executes a KQL query and returns the results as variable values. See [Create a Logs variable](#create-a-logs-variable). | +| **Custom Namespaces** | Returns custom metric namespaces for a specified resource. | +| **Custom Metric Names** | Returns custom metric names for a specified resource. | {{< admonition type="note" >}} -Custom metrics cannot be emitted against a subscription or resource group. Select resources only when you need to retrieve custom metric namespaces or custom metric names associated with a specific resource. +Custom metrics cannot be emitted against a subscription or resource group. Select specific resources when retrieving custom metric namespaces or custom metric names. {{< /admonition >}} -You can use any Log Analytics Kusto Query Language (KQL) query that returns a single list of values in the `Query` field. -For example: +## Create cascading variables -| Query | List of values returned | -| ----------------------------------------------------------------------------------------- | --------------------------------------- | -| `workspace("myWorkspace").Heartbeat \| distinct Computer` | Virtual machines | -| `workspace("$workspace").Heartbeat \| distinct Computer` | Virtual machines with template variable | -| `workspace("$workspace").Perf \| distinct ObjectName` | Objects from the Perf table | -| `workspace("$workspace").Perf \| where ObjectName == "$object"` `\| distinct CounterName` | Metric names from the Perf table | +Cascading variables (also called dependent or chained variables) allow you to create dropdown menus that filter based on previous selections. This is useful for drilling down from subscription to resource group to specific resource. -### Query variable example +### Example: Subscription → Resource Group → Resource Name -This time series query uses query variables: +**Step 1: Create a Subscription variable** + +1. Create a variable named `subscription`. +1. Set **Query Type** to **Subscriptions**. + +**Step 2: Create a Resource Group variable** + +1. Create a variable named `resourceGroup`. +1. Set **Query Type** to **Resource Groups**. +1. In the **Subscription** field, select `$subscription`. + +**Step 3: Create a Resource Name variable** + +1. Create a variable named `resource`. +1. Set **Query Type** to **Resource Names**. +1. In the **Subscription** field, select `$subscription`. +1. In the **Resource Group** field, select `$resourceGroup`. +1. Select the appropriate **Namespace** for your resources (e.g., `Microsoft.Compute/virtualMachines`). + +Now when you change the subscription, the resource group dropdown updates automatically, and when you change the resource group, the resource name dropdown updates. + +## Create a Logs variable + +The **Logs** query type lets you use a KQL query to populate variable values. The query must return a single column of values. + +**To create a Logs variable:** + +1. Create a new variable with **Query Type** set to **Logs**. +1. Select a **Resource** (Log Analytics workspace or Application Insights resource). +1. Enter a KQL query that returns a single column. + +### Logs variable query examples + +| Query | Returns | +| ----------------------------------------- | ------------------------------------- | +| `Heartbeat \| distinct Computer` | List of virtual machine names | +| `Perf \| distinct ObjectName` | List of performance object names | +| `AzureActivity \| distinct ResourceGroup` | List of resource groups with activity | +| `AppRequests \| distinct Name` | List of application request names | + +You can reference other variables in your Logs query: + +```kusto +workspace("$workspace").Heartbeat | distinct Computer +``` + +```kusto +workspace("$workspace").Perf +| where ObjectName == "$object" +| distinct CounterName +``` + +## Variable refresh options + +Control when your variables refresh by setting the **Refresh** option: + +| Option | Behavior | +| ------------------------ | ----------------------------------------------------------------------------------------- | +| **On dashboard load** | Variables refresh each time the dashboard loads. Best for data that changes infrequently. | +| **On time range change** | Variables refresh when the dashboard time range changes. Use for time-sensitive queries. | + +For dashboards with many variables or complex queries, use **On dashboard load** to improve performance. + +## Use variables in queries + +After you create template variables, you can use them in your Azure Monitor queries by referencing them with the `$` prefix. + +### Metrics query example + +In a Metrics query, select your variables in the resource picker fields: + +- **Subscription**: `$subscription` +- **Resource Group**: `$resourceGroup` +- **Resource Name**: `$resource` + +### Logs query example + +Reference variables directly in your KQL queries: ```kusto Perf | where ObjectName == "$object" and CounterName == "$metric" | where TimeGenerated >= $__timeFrom() and TimeGenerated <= $__timeTo() -| where $__contains(Computer, $computer) +| where $__contains(Computer, $computer) | summarize avg(CounterValue) by bin(TimeGenerated, $__interval), Computer | order by TimeGenerated asc ``` -### Multi-value variables +## Multi-value variables -It is possible to select multiple values for **Resource Groups** and **Resource Names** and use a single metrics query pointing to those values as long as they: +You can enable **Multi-value** selection for **Resource Groups** and **Resource Names** variables. When using multi-value variables in a Metrics query, all selected resources must: -- Belong to the same subscription. -- Are in the same region. -- Are of the same type (namespace). +- Belong to the same subscription +- Be in the same Azure region +- Be of the same resource type (namespace) -Also, note that if a template variable pointing to multiple resource groups or names is used in another template variable as a parameter (e.g. to retrieve metric names), only the first value will be used. This means that the combination of the first resource group and name selected should be valid. +{{< admonition type="note" >}} +When a multi-value variable is used as a parameter in another variable query (for example, to retrieve metric names), only the first selected value is used. Ensure the first resource group and resource name combination is valid. +{{< /admonition >}} + +## Troubleshoot template variables + +If you encounter issues with template variables, try the following solutions. + +### Variable returns no values + +- Verify the Azure Monitor data source is configured correctly and can connect to Azure. +- Check that the credentials have appropriate permissions to list the requested resources. +- For cascading variables, ensure parent variables have valid selections. + +### Variable values are outdated + +- Check the **Refresh** setting and adjust if needed. +- Click the refresh icon next to the variable dropdown to manually refresh. + +### Multi-value selection not working in queries + +- Ensure the resources meet the requirements (same subscription, region, and type). +- For Logs queries, use the `$__contains()` macro to handle multi-value variables properly. diff --git a/docs/sources/datasources/azure-monitor/troubleshooting/index.md b/docs/sources/datasources/azure-monitor/troubleshooting/index.md new file mode 100644 index 00000000000..b2d5a9efc32 --- /dev/null +++ b/docs/sources/datasources/azure-monitor/troubleshooting/index.md @@ -0,0 +1,320 @@ +--- +aliases: + - ../../data-sources/azure-monitor/troubleshooting/ +description: Troubleshooting guide for the Azure Monitor data source in Grafana +keywords: + - grafana + - azure + - monitor + - troubleshooting + - errors + - authentication + - query +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Troubleshoot +title: Troubleshoot Azure Monitor data source issues +weight: 500 +last_reviewed: 2025-12-04 +refs: + configure-azure-monitor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/configure/ + template-variables: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/template-variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/template-variables/ + query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/azure-monitor/query-editor/ +--- + +# Troubleshoot Azure Monitor data source issues + +This document provides solutions to common issues you may encounter when configuring or using the Azure Monitor data source. + +## Configuration and authentication errors + +These errors typically occur when setting up the data source or when authentication credentials are invalid. + +### "Authorization failed" or "Access denied" + +**Symptoms:** + +- Save & test fails with "Authorization failed" +- Queries return "Access denied" errors +- Subscriptions don't load when clicking **Load Subscriptions** + +**Possible causes and solutions:** + +| Cause | Solution | +| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| App registration doesn't have required permissions | Assign the `Reader` role to the app registration on the subscription or resource group you want to monitor. Refer to the [Azure documentation for role assignments](https://docs.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal?tabs=current). | +| Incorrect tenant ID, client ID, or client secret | Verify the credentials in the Azure Portal under **App registrations** > your app > **Overview** (for IDs) and **Certificates & secrets** (for secret). | +| Client secret has expired | Create a new client secret in Azure and update the data source configuration. | +| Managed Identity not enabled on the Azure resource | For VMs, enable managed identity in the Azure Portal under **Identity**. For App Service, enable it under **Identity** in the app settings. | +| Managed Identity not assigned the Reader role | Assign the `Reader` role to the managed identity on the target subscription or resources. | + +### "Invalid client secret" or "Client secret not found" + +**Symptoms:** + +- Authentication fails immediately after configuration +- Error message references invalid credentials + +**Solutions:** + +1. Ensure you copied the client secret **value**, not the secret ID. In Azure Portal under **Certificates & secrets**, the secret value is only shown once when created. The secret ID is a different identifier and won't work for authentication. +2. Verify the client secret was copied correctly (no extra spaces or truncation). +3. Check if the secret has expired in Azure Portal under **App registrations** > your app > **Certificates & secrets**. +4. Create a new secret and update the data source configuration. + +### "Tenant not found" or "Invalid tenant ID" + +**Symptoms:** + +- Data source test fails with tenant-related errors +- Unable to authenticate + +**Solutions:** + +1. Verify the Directory (tenant) ID in Azure Portal under **Microsoft Entra ID** > **Overview**. +2. Ensure you're using the correct Azure cloud setting (Azure, Azure Government, or Azure China). +3. Check that the tenant ID is a valid GUID format. + +### Managed Identity not working + +**Symptoms:** + +- Managed Identity option is available but authentication fails +- Error: "Managed identity authentication is not available" + +**Solutions:** + +1. Verify `managed_identity_enabled = true` is set in the Grafana server configuration under `[azure]`. +2. Confirm the Azure resource hosting Grafana has managed identity enabled. +3. For user-assigned managed identity, ensure `managed_identity_client_id` is set correctly. +4. Verify the managed identity has the `Reader` role on the target resources. +5. Restart Grafana after changing server configuration. + +### Workload Identity not working + +**Symptoms:** + +- Workload Identity authentication fails in Kubernetes/AKS environment +- Token file errors + +**Solutions:** + +1. Verify `workload_identity_enabled = true` is set in the Grafana server configuration. +2. Check that the service account is correctly annotated for workload identity. +3. Verify the federated credential is configured in Azure. +4. Ensure the token path is accessible to the Grafana pod. +5. Check the workload identity webhook is running in the cluster. + +## Query errors + +These errors occur when executing queries against Azure Monitor services. + +### "No data" or empty results + +**Symptoms:** + +- Query executes without error but returns no data +- Charts show "No data" message + +**Possible causes and solutions:** + +| Cause | Solution | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | +| Time range doesn't contain data | Expand the dashboard time range or verify data exists in Azure Portal. | +| Wrong resource selected | Verify you've selected the correct subscription, resource group, and resource. | +| Metric not available for resource | Not all metrics are available for all resources. Check available metrics in Azure Portal under the resource's **Metrics** blade. | +| Metric has no values | Some metrics only populate under certain conditions (e.g., error counts when errors occur). | +| Permissions issue | Verify the identity has read access to the specific resource. | + +### "Bad request" or "Invalid query" + +**Symptoms:** + +- Query fails with 400 error +- Error message indicates query syntax issues + +**Solutions for Logs queries:** + +1. Validate your KQL syntax in the Azure Portal Log Analytics query editor. +2. Check for typos in table names or column names. +3. Ensure referenced tables exist in the selected workspace. +4. Verify the time range is valid (not in the future, not too far in the past for data retention). + +**Solutions for Metrics queries:** + +1. Verify the metric name is valid for the selected resource type. +2. Check that dimension filters use valid dimension names and values. +3. Ensure the aggregation type is supported for the selected metric. + +### "Resource not found" + +**Symptoms:** + +- Query fails with 404 error +- Resource picker shows resources that can't be queried + +**Solutions:** + +1. Verify the resource still exists in Azure (it may have been deleted or moved). +2. Check that the subscription is correct. +3. Refresh the resource picker by re-selecting the subscription. +4. Verify the identity has access to the resource's resource group. + +### Logs query timeout + +**Symptoms:** + +- Query runs for a long time then fails +- Error mentions timeout or query limits + +**Solutions:** + +1. Narrow the time range to reduce data volume. +2. Add filters to reduce the result set. +3. Use `summarize` to aggregate data instead of returning raw rows. +4. Consider using Basic Logs for large datasets (if enabled). +5. Break complex queries into smaller parts. + +### "Metrics not available" for a resource + +**Symptoms:** + +- Resource appears in picker but no metrics are listed +- Metric dropdown is empty + +**Solutions:** + +1. Verify the resource type supports Azure Monitor metrics. +2. Check if the resource is in a region that supports metrics. +3. Some resources require diagnostic settings to emit metrics—configure these in Azure Portal. +4. Try selecting a different namespace for the resource. + +## Azure Resource Graph errors + +These errors are specific to Azure Resource Graph (ARG) queries. + +### "Query execution failed" + +**Symptoms:** + +- ARG query fails with execution errors +- Results don't match expected resources + +**Solutions:** + +1. Validate query syntax in Azure Portal Resource Graph Explorer. +2. Check that you have access to the subscriptions being queried. +3. Verify table names are correct (e.g., `Resources`, `ResourceContainers`). +4. Some ARG features require specific permissions, check [ARG documentation](https://docs.microsoft.com/en-us/azure/governance/resource-graph/). + +### Query returns incomplete results + +**Symptoms:** + +- Not all expected resources appear in results +- Results seem truncated + +**Solutions:** + +1. ARG queries are paginated. The data source handles pagination automatically, but very large result sets may be limited. +2. Add filters to reduce result set size. +3. Verify you have access to all subscriptions containing the resources. + +## Application Insights Traces errors + +These errors are specific to the Traces query type. + +### "No traces found" + +**Symptoms:** + +- Trace query returns empty results +- Operation ID search finds nothing + +**Solutions:** + +1. Verify the Application Insights resource is collecting trace data. +2. Check that the time range includes when the traces were generated. +3. Ensure the Operation ID is correct (copy directly from another trace or log). +4. Verify the identity has access to the Application Insights resource. + +## Template variable errors + +For detailed troubleshooting of template variables, refer to the [template variables troubleshooting section](ref:template-variables). + +### Variables return no values + +**Solutions:** + +1. Verify the data source connection is working (test it in the data source settings). +2. Check that parent variables (for cascading variables) have valid selections. +3. Verify the identity has permissions to list the requested resources. +4. For Logs variables, ensure the KQL query returns a single column. + +### Variables are slow to load + +**Solutions:** + +1. Set variable refresh to **On dashboard load** instead of **On time range change**. +2. Reduce the scope of variable queries (e.g., filter by resource group instead of entire subscription). +3. For Logs variables, optimize the KQL query to return results faster. + +## Connection and network errors + +These errors indicate problems with network connectivity between Grafana and Azure services. + +### "Connection refused" or timeout errors + +**Symptoms:** + +- Data source test fails with network errors +- Queries timeout without returning results + +**Solutions:** + +1. Verify network connectivity from Grafana to Azure endpoints. +2. Check firewall rules allow outbound HTTPS (port 443) to Azure services. +3. For private networks, ensure Private Link or VPN is configured correctly. +4. For Grafana Cloud, configure [Private Data Source Connect](ref:configure-azure-monitor) if accessing private resources. + +### SSL/TLS certificate errors + +**Symptoms:** + +- Certificate validation failures +- SSL handshake errors + +**Solutions:** + +1. Ensure the system time is correct (certificate validation fails with incorrect time). +2. Verify corporate proxy isn't intercepting HTTPS traffic. +3. Check that required CA certificates are installed on the Grafana server. + +## Get additional help + +If you've tried the solutions above and still encounter issues: + +1. Check the [Grafana community forums](https://community.grafana.com/) for similar issues. +1. Review the [Azure Monitor data source GitHub issues](https://github.com/grafana/grafana/issues) for known bugs. +1. Enable debug logging in Grafana to capture detailed error information. +1. Contact Grafana Support if you're an Enterprise, Cloud Pro or Cloud Contracted user. +1. When reporting issues, include: + - Grafana version + - Error messages (redact sensitive information) + - Steps to reproduce + - Relevant configuration (redact credentials) diff --git a/docs/sources/datasources/elasticsearch/_index.md b/docs/sources/datasources/elasticsearch/_index.md index 1143dbdc68b..ebee19b2dcb 100644 --- a/docs/sources/datasources/elasticsearch/_index.md +++ b/docs/sources/datasources/elasticsearch/_index.md @@ -17,16 +17,6 @@ menuTitle: Elasticsearch title: Elasticsearch data source weight: 325 refs: - configuration: - - pattern: /docs/grafana/ - destination: /docs/grafana//setup-grafana/configure-grafana/#sigv4_auth_enabled - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//setup-grafana/configure-grafana/#sigv4_auth_enabled - provisioning-grafana: - - pattern: /docs/grafana/ - destination: /docs/grafana//administration/provisioning/#data-sources - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//administration/provisioning/#data-sources explore: - pattern: /docs/grafana/ destination: /docs/grafana//explore/ @@ -44,12 +34,36 @@ refs: Elasticsearch is a search and analytics engine used for a variety of use cases. You can create many types of queries to visualize logs or metrics stored in Elasticsearch, and annotate graphs with log events stored in Elasticsearch. -The following will help you get started working with Elasticsearch and Grafana: +The following resources will help you get started with Elasticsearch and Grafana: - [What is Elasticsearch?](https://www.elastic.co/guide/en/elasticsearch/reference/current/elasticsearch-intro.html) -- [Configure the Elasticsearch data source](/docs/grafana/latest/datasources/elasticsearch/configure-elasticsearch-data-source/) -- [Elasticsearch query editor](query-editor/) -- [Elasticsearch template variables](template-variables/) +- [Configure the Elasticsearch data source](https://grafana.com/docs/grafana//datasources/elasticsearch/configure/) +- [Elasticsearch query editor](https://grafana.com/docs/grafana//datasources/elasticsearch/query-editor/) +- [Elasticsearch template variables](https://grafana.com/docs/grafana//datasources/elasticsearch/template-variables/) +- [Elasticsearch annotations](https://grafana.com/docs/grafana//datasources/elasticsearch/annotations/) +- [Elasticsearch alerting](https://grafana.com/docs/grafana//datasources/elasticsearch/alerting/) +- [Troubleshooting issues with the Elasticsearch data source](https://grafana.com/docs/grafana//datasources/elasticsearch/troubleshooting/) + +## Key capabilities + +The Elasticsearch data source supports: + +- **Metrics queries:** Aggregate and visualize numeric data using bucket and metric aggregations. +- **Log queries:** Search, filter, and explore log data with Lucene query syntax. +- **Annotations:** Overlay Elasticsearch events on your dashboard graphs. +- **Alerting:** Create alerts based on Elasticsearch query results. + +## Before you begin + +Before you configure the Elasticsearch data source, you need: + +- An Elasticsearch instance (v7.17+, v8.x, or v9.x) +- Network access from Grafana to your Elasticsearch server +- Appropriate user credentials or API keys with read access + +{{< admonition type="note" >}} +If you use Amazon OpenSearch Service (the successor to Amazon Elasticsearch Service), use the [OpenSearch data source](https://grafana.com/docs/grafana//datasources/opensearch/) instead. +{{< /admonition >}} ## Supported Elasticsearch versions @@ -63,86 +77,18 @@ This data source supports these versions of Elasticsearch: - v8.x - v9.x -Our maintenance policy for Elasticsearch data source is aligned with the [Elastic Product End of Life Dates](https://www.elastic.co/support/eol) and we ensure proper functionality for supported versions. If you are using an Elasticsearch with version that is past its end-of-life (EOL), you can still execute queries, but you will receive a notification in the query builder indicating that the version of Elasticsearch you are using is no longer supported. It's important to note that in such cases, we do not guarantee the correctness of the functionality, and we will not be addressing any related issues. +The Grafana maintenance policy for the Elasticsearch data source aligns with [Elastic Product End of Life Dates](https://www.elastic.co/support/eol). Grafana ensures proper functionality for supported versions only. If you use an EOL version of Elasticsearch, you can still run queries, but the query builder displays a warning. Grafana doesn't guarantee functionality or provide fixes for EOL versions. -## Provision the data source +## Additional resources -You can define and configure the data source in YAML files as part of Grafana's provisioning system. -For more information about provisioning, and for available configuration options, refer to [Provisioning Grafana](ref:provisioning-grafana). +Once you have configured the Elasticsearch data source, you can: -{{< admonition type="note" >}} -The previously used `database` field has now been [deprecated](https://github.com/grafana/grafana/pull/58647). -You should now use the `index` field in `jsonData` to store the index name. -Please see the examples below. -{{< /admonition >}} +- Use [Explore](ref:explore) to run ad-hoc queries against your Elasticsearch data. +- Configure and use [template variables](https://grafana.com/docs/grafana//datasources/elasticsearch/template-variables/) for dynamic dashboards. +- Add [Transformations](https://grafana.com/docs/grafana//panels-visualizations/query-transform-data/transform-data/) to process query results. +- [Build dashboards](ref:build-dashboards) to visualize your Elasticsearch data. -### Provisioning examples +## Related data sources -**Basic provisioning** - -```yaml -apiVersion: 1 - -datasources: - - name: Elastic - type: elasticsearch - access: proxy - url: http://localhost:9200 - jsonData: - index: '[metrics-]YYYY.MM.DD' - interval: Daily - timeField: '@timestamp' -``` - -**Provision for logs** - -```yaml -apiVersion: 1 - -datasources: - - name: elasticsearch-v7-filebeat - type: elasticsearch - access: proxy - url: http://localhost:9200 - jsonData: - index: '[filebeat-]YYYY.MM.DD' - interval: Daily - timeField: '@timestamp' - logMessageField: message - logLevelField: fields.level - dataLinks: - - datasourceUid: my_jaeger_uid # Target UID needs to be known - field: traceID - url: '$${__value.raw}' # Careful about the double "$$" because of env var expansion -``` - -## Configure Amazon Elasticsearch Service - -If you use Amazon Elasticsearch Service, you can use Grafana's Elasticsearch data source to visualize data from it. - -If you use an AWS Identity and Access Management (IAM) policy to control access to your Amazon Elasticsearch Service domain, you must use AWS Signature Version 4 (AWS SigV4) to sign all requests to that domain. - -For details on AWS SigV4, refer to the [AWS documentation](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html). - -### AWS Signature Version 4 authentication - -To sign requests to your Amazon Elasticsearch Service domain, you can enable SigV4 in Grafana's [configuration](ref:configuration). - -Once AWS SigV4 is enabled, you can configure it on the Elasticsearch data source configuration page. -For more information about AWS authentication options, refer to [AWS authentication](../aws-cloudwatch/aws-authentication/). - -{{< figure src="/static/img/docs/v73/elasticsearch-sigv4-config-editor.png" max-width="500px" class="docs-image--no-shadow" caption="SigV4 configuration for AWS Elasticsearch Service" >}} - -## Query the data source - -You can select multiple metrics and group by multiple terms or filters when using the Elasticsearch query editor. - -For details, see the [query editor documentation](query-editor/). - -## Use template variables - -Instead of hard-coding details such as server, application, and sensor names in metric queries, you can use variables. -Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. -Grafana refers to such variables as template variables. - -For details, see the [template variables documentation](template-variables/). +- [OpenSearch](https://grafana.com/docs/grafana//datasources/opensearch/) - For Amazon OpenSearch Service. +- [Loki](https://grafana.com/docs/grafana//datasources/loki/) - Grafana's log aggregation system. diff --git a/docs/sources/datasources/elasticsearch/alerting/index.md b/docs/sources/datasources/elasticsearch/alerting/index.md new file mode 100644 index 00000000000..ef002764bda --- /dev/null +++ b/docs/sources/datasources/elasticsearch/alerting/index.md @@ -0,0 +1,144 @@ +--- +aliases: + - ../../data-sources/elasticsearch/alerting/ +description: Using Grafana Alerting with the Elasticsearch data source +keywords: + - grafana + - elasticsearch + - alerting + - alerts +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Alerting +title: Elasticsearch alerting +weight: 550 +refs: + alerting: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/ + create-alert-rule: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/alerting-rules/create-grafana-managed-rule/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/create-grafana-managed-rule/ +--- + +# Elasticsearch alerting + +You can use Grafana Alerting with Elasticsearch to create alerts based on your Elasticsearch data. This allows you to monitor metrics, detect anomalies, and receive notifications when specific conditions are met. + +For general information about Grafana Alerting, refer to [Grafana Alerting](ref:alerting). + +## Before you begin + +Before creating alerts with Elasticsearch, ensure you have: + +- An Elasticsearch data source configured in Grafana +- Appropriate permissions to create alert rules +- Understanding of the metrics you want to monitor + +## Supported query types + +Elasticsearch alerting works best with **metrics queries** that return time series data. To create a valid alert query: + +- Use a **Date histogram** as the last bucket aggregation (under **Group by**) +- Select appropriate metric aggregations (Count, Average, Sum, Min, Max, etc.) + +Queries that return time series data allow Grafana to evaluate values over time and trigger alerts when thresholds are crossed. + +### Query types and alerting compatibility + +| Query type | Alerting support | Notes | +| ------------------------------ | ---------------- | ----------------------------------------------------------- | +| Metrics with Date histogram | ✅ Full support | Recommended for alerting | +| Metrics without Date histogram | ⚠️ Limited | May not evaluate correctly over time | +| Logs | ❌ Not supported | Use metrics queries instead | +| Raw data | ❌ Not supported | Use metrics queries instead | +| Raw document (deprecated) | ❌ Not supported | Deprecated since Grafana v10.1. Use metrics queries instead | + +## Create an alert rule + +To create an alert rule using Elasticsearch: + +1. Navigate to **Alerting** > **Alert rules**. +1. Click **New alert rule**. +1. Enter a name for the alert rule. +1. Select your **Elasticsearch** data source. +1. Build your query using the query editor: + - Add metric aggregations (for example, Average, Count, Sum) + - Add a Date histogram under **Group by** + - Optionally add filters using Lucene query syntax +1. Configure the alert condition (for example, when the average is above a threshold). +1. Set the evaluation interval and pending period. +1. Configure notifications and labels. +1. Click **Save rule**. + +For detailed instructions, refer to [Create a Grafana-managed alert rule](ref:create-alert-rule). + +## Example alert queries + +The following examples show common alerting scenarios with Elasticsearch. + +### Alert on high error count + +Monitor the number of error-level log entries: + +1. **Query:** `level:error` +1. **Metric:** Count +1. **Group by:** Date histogram (interval: 1m) +1. **Condition:** When count is above 100 + +### Alert on average response time + +Monitor API response times: + +1. **Query:** `type:api_request` +1. **Metric:** Average on field `response_time` +1. **Group by:** Date histogram (interval: 5m) +1. **Condition:** When average is above 500 (milliseconds) + +### Alert on unique user count drop + +Detect drops in active users: + +1. **Query:** `*` (all documents) +1. **Metric:** Unique count on field `user_id` +1. **Group by:** Date histogram (interval: 1h) +1. **Condition:** When unique count is below 100 + +## Limitations + +When using Elasticsearch with Grafana Alerting, be aware of the following limitations: + +### Template variables not supported + +Alert queries cannot contain template variables. Grafana evaluates alert rules on the backend without dashboard context, so variables like `$hostname` or `$environment` won't be resolved. + +If your dashboard query uses template variables, create a separate query for alerting with hard coded values. + +### Logs queries not supported + +Queries using the **Logs** metric type cannot be used for alerting. Convert your query to use metric aggregations with a Date histogram instead. + +### Query complexity + +Complex queries with many nested aggregations may timeout or fail to evaluate. Simplify queries for alerting by: + +- Reducing the number of bucket aggregations +- Using appropriate time intervals +- Adding filters to limit the data scanned + +## Best practices + +Follow these best practices when creating Elasticsearch alerts: + +- **Use specific filters:** Add Lucene query filters to focus on relevant data and improve query performance. +- **Choose appropriate intervals:** Match the Date histogram interval to your evaluation frequency. +- **Test queries first:** Verify your query returns expected results in Explore before creating an alert. +- **Set realistic thresholds:** Base alert thresholds on historical data patterns. +- **Use meaningful names:** Give alert rules descriptive names that indicate what they monitor. diff --git a/docs/sources/datasources/elasticsearch/annotations/index.md b/docs/sources/datasources/elasticsearch/annotations/index.md new file mode 100644 index 00000000000..788cfe15ff6 --- /dev/null +++ b/docs/sources/datasources/elasticsearch/annotations/index.md @@ -0,0 +1,124 @@ +--- +aliases: + - ../../data-sources/elasticsearch/annotations/ +description: Using annotations with Elasticsearch in Grafana +keywords: + - grafana + - elasticsearch + - annotations + - events +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Annotations +title: Elasticsearch annotations +weight: 500 +refs: + annotate-visualizations: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/build-dashboards/annotate-visualizations/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/build-dashboards/annotate-visualizations/ +--- + +# Elasticsearch annotations + +Annotations overlay event data on your dashboard graphs, helping you correlate log events with metrics. +You can use Elasticsearch as a data source for annotations to display events such as deployments, alerts, or other significant occurrences on your visualizations. + +For general information about annotations, refer to [Annotate visualizations](ref:annotate-visualizations). + +## Before you begin + +Before creating Elasticsearch annotations, ensure you have: + +- An Elasticsearch data source configured in Grafana +- Documents in Elasticsearch containing event data with timestamp fields +- Read access to the Elasticsearch index containing your events + +## Create an annotation query + +To add an Elasticsearch annotation to your dashboard: + +1. Navigate to your dashboard and click **Dashboard settings** (gear icon). +1. Select **Annotations** in the left menu. +1. Click **Add annotation query**. +1. Enter a **Name** for the annotation. +1. Select your **Elasticsearch** data source from the **Data source** drop-down. +1. Configure the annotation query and field mappings. +1. Click **Save dashboard**. + +## Query + +Use the query field to filter which Elasticsearch documents appear as annotations. The query uses [Lucene query syntax](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax). + +**Examples:** + +| Query | Description | +| ---------------------------------------- | ---------------------------------------------------- | +| `*` | Matches all documents. | +| `type:deployment` | Shows only deployment events. | +| `level:error OR level:critical` | Shows error and critical events. | +| `service:api AND environment:production` | Shows events for a specific service and environment. | +| `tags:release` | Shows events tagged as releases. | + +You can use template variables in your annotation queries. For example, `service:$service` filters annotations based on the selected service variable. + +## Field mappings + +Field mappings tell Grafana which Elasticsearch fields contain the annotation data. + +### Time + +The **Time** field specifies which field contains the annotation timestamp. + +- **Default:** `@timestamp` +- **Format:** The field must contain a date value that Elasticsearch recognizes. + +### Time End + +The **Time End** field specifies a field containing the end time for range annotations. Range annotations display as a shaded region on the graph instead of a single vertical line. + +- **Default:** Empty (single-point annotations) +- **Use case:** Display maintenance windows, incidents, or any event with a duration. + +### Text + +The **Text** field specifies which field contains the annotation description displayed when you hover over the annotation. + +- **Default:** `tags` +- **Tip:** Use a descriptive field like `message`, `description`, or `summary`. + +### Tags + +The **Tags** field specifies which field contains tags for the annotation. Tags help categorize and filter annotations. + +- **Default:** Empty +- **Format:** The field can contain either a comma-separated string or an array of strings. + +## Example: Deployment annotations + +To display deployment events as annotations: + +1. Create an annotation query with the following settings: + - **Query:** `type:deployment` + - **Time:** `@timestamp` + - **Text:** `message` + - **Tags:** `environment` + +This configuration displays deployment events with their messages as the annotation text and environments as tags. + +## Example: Range annotations for incidents + +To display incidents with duration: + +1. Create an annotation query with the following settings: + - **Query:** `type:incident` + - **Time:** `start_time` + - **Time End:** `end_time` + - **Text:** `description` + - **Tags:** `severity` + +This configuration displays incidents as shaded regions from their start time to end time. diff --git a/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md b/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md deleted file mode 100644 index 6b145841bbf..00000000000 --- a/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md +++ /dev/null @@ -1,207 +0,0 @@ ---- -aliases: - - ../data-sources/elasticsearch/ - - ../features/datasources/elasticsearch/ -description: Guide for configuring the Elasticsearch data source in Grafana -keywords: - - grafana - - elasticsearch - - guide - - data source -labels: - products: - - cloud - - enterprise - - oss -menuTitle: Configure Elasticsearch -title: Configure the Elasticsearch data source -weight: 200 -refs: - administration-documentation: - - pattern: /docs/grafana/ - destination: /docs/grafana//administration/data-source-management/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//administration/data-source-management/ - supported-expressions: - - pattern: /docs/grafana/ - destination: /docs/grafana//explore/logs-integration/#log-level - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//explore/logs-integration/#log-level - query-and-transform-data: - - pattern: /docs/grafana/ - destination: /docs/grafana//panels-visualizations/query-transform-data/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/ - provisioning-data-source: - - pattern: /docs/grafana/ - destination: /docs/grafana//datasources/elasticsearch/#provision-the-data-source - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/connect-externally-hosted/data-sources/elasticsearch/#provision-the-data-source ---- - -# Configure the Elasticsearch data source - -Grafana ships with built-in support for Elasticsearch. -You can create a variety of queries to visualize logs or metrics stored in Elasticsearch, and annotate graphs with log events stored in Elasticsearch. - -For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref:administration-documentation). - -Only users with the organization `administrator` role can add data sources. -Administrators can also [configure the data source via YAML](ref:provisioning-data-source) with Grafana's provisioning system. - -## Configuring permissions - -When Elasticsearch security features are enabled, it is essential to configure the necessary cluster privileges to ensure seamless operation. Below is a list of the required privileges along with their purposes: - -- **monitor** - Necessary to retrieve the version information of the connected Elasticsearch instance. -- **view_index_metadata** - Required for accessing mapping definitions of indices. -- **read** - Grants the ability to perform search and retrieval operations on indices. This is essential for querying and extracting data from the cluster. - -## Add the data source - -To add the Elasticsearch data source, complete the following steps: - -1. Click **Connections** in the left-side menu. -1. Under **Connections**, click **Add new connection**. -1. Enter `Elasticsearch` in the search bar. -1. Click **Elasticsearch** under the **Data source** section. -1. Click **Add new data source** in the upper right. - -You will be taken to the **Settings** tab where you will set up your Elasticsearch configuration. - -## Configuration options - -The following is a list of configuration options for Elasticsearch. - -The first option to configure is the name of your connection: - -- **Name** - The data source name. This is how you refer to the data source in panels and queries. Examples: elastic-1, elasticsearch_metrics. - -- **Default** - Toggle to select as the default data source option. When you go to a dashboard panel or Explore, this will be the default selected data source. - -## Connection - -Connect the Elasticsearch data source by specifying a URL. - -- **URL** - The URL of your Elasticsearch server. If your Elasticsearch server is local, use `http://localhost:9200`. If it is on a server within a network, this is the URL with the port where you are running Elasticsearch. Example: `http://elasticsearch.example.orgname:9200`. - -## Authentication - -There are several authentication methods you can choose in the Authentication section. -Select one of the following authentication methods from the dropdown menu. - -- **Basic authentication** - The most common authentication method. Use your `data source` user name and `data source` password to connect. - -- **Forward OAuth identity** - Forward the OAuth access token (and the OIDC ID token if available) of the user querying the data source. - -- **No authentication** - Make the data source available without authentication. Grafana recommends using some type of authentication method. - - - -### TLS settings - -{{< admonition type="note" >}} -Use TLS (Transport Layer Security) for an additional layer of security when working with Elasticsearch. For information on setting up TLS encryption with Elasticsearch see [Configure TLS](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/configuring-tls.html#configuring-tls). You must add TLS settings to your Elasticsearch configuration file **prior** to setting these options in Grafana. -{{< /admonition >}} - -- **Add self-signed certificate** - Check the box to authenticate with a CA certificate. Follow the instructions of the CA (Certificate Authority) to download the certificate file. Required for verifying self-signed TLS certificates. - -- **TLS client authentication** - Check the box to authenticate with the TLS client, where the server authenticates the client. Add the `Server name`, `Client certificate` and `Client key`. The **ServerName** is used to verify the hostname on the returned certificate. The **Client certificate** can be generated from a Certificate Authority (CA) or be self-signed. The **Client key** can also be generated from a Certificate Authority (CA) or be self-signed. The client key encrypts the data between client and server. - -- **Skip TLS certificate validation** - Check the box to bypass TLS certificate validation. Skipping TLS certificate validation is not recommended unless absolutely necessary or for testing purposes. - -### HTTP headers - -Click **+ Add header** to add one or more HTTP headers. HTTP headers pass additional context and metadata about the request/response. - -- **Header** - Add a custom header. This allows custom headers to be passed based on the needs of your Elasticsearch instance. - -- **Value** - The value of the header. - -## Additional settings - -Additional settings are optional settings that can be configured for more control over your data source. - -### Advanced HTTP settings - -- **Allowed cookies** - Specify cookies by name that should be forwarded to the data source. The Grafana proxy deletes all forwarded cookies by default. - -- **Timeout** - The HTTP request timeout. This must be in seconds. There is no default, so this setting is up to you. - -### Elasticsearch details - -The following settings are specific to the Elasticsearch data source. - -- **Index name** - Use the index settings to specify a default for the `time field` and your Elasticsearch index's name. You can use a time pattern, for example `[logstash-]YYYY.MM.DD`, or a wildcard for the index name. When specifying a time pattern, the fixed part(s) of the pattern should be wrapped in square brackets. - -- **Pattern** - Select the matching pattern if using one in your index name. Options include: - - no pattern - - hourly - - daily - - weekly - - monthly - - yearly - -Only select a pattern option if you have specified a time pattern in the Index name field. - -- **Time field name** - Name of the time field. The default value is @timestamp. You can enter a different name. - -- **Max concurrent shard requests** - Sets the number of shards being queried at the same time. The default is `5`. For more information on shards see [Elasticsearch's documentation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/scalability.html#scalability). - -- **Min time interval** - Defines a lower limit for the auto group-by time interval. This value **must** be formatted as a number followed by a valid time identifier: - - | Identifier | Description | - | ---------- | ----------- | - | `y` | year | - | `M` | month | - | `w` | week | - | `d` | day | - | `h` | hour | - | `m` | minute | - | `s` | second | - | `ms` | millisecond | - -We recommend setting this value to match your Elasticsearch write frequency. -For example, set this to `1m` if Elasticsearch writes data every minute. - -You can also override this setting in a dashboard panel under its data source options. The default is `10s`. - -- **X-Pack enabled** - Toggle to enable `X-Pack`-specific features and options, which provide the [query editor](../query-editor/) with additional aggregations, such as `Rate` and `Top Metrics`. - -- **Include frozen indices** - Toggle on when the `X-Pack enabled` setting is active. Includes frozen indices in searches. You can configure Grafana to include [frozen indices](https://www.elastic.co/guide/en/elasticsearch/reference/7.13/frozen-indices.html) when performing search requests. - -{{< admonition type="note" >}} -Frozen indices are [deprecated in Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/frozen-indices.html) since v7.14. -{{< /admonition >}} - -### Logs - -In this section you can configure which fields the data source uses for log messages and log levels. - -- **Message field name:** - Grabs the actual log message from the default source. - -- **Level field name:** - Name of the field with log level/severity information. When a level label is specified, the value of this label is used to determine the log level and update the color of each log line accordingly. If the log doesn’t have a specified level label, we try to determine if its content matches any of the [supported expressions](ref:supported-expressions). The first match always determines the log level. If Grafana cannot infer a log-level field, it will be visualized with an unknown log level. - -### Data links - -Data links create a link from a specified field that can be accessed in Explore's logs view. You can add multiple data links by clicking **+ Add**. - -Each data link configuration consists of: - -- **Field** - Sets the name of the field used by the data link. - -- **URL/query** - Sets the full link URL if the link is external. If the link is internal, this input serves as a query for the target data source.
In both cases, you can interpolate the value from the field with the `${__value.raw }` macro. - -- **URL Label** (Optional) - Sets a custom display label for the link. The link label defaults to the full external URL or name of the linked internal data source and is overridden by this setting. - -- **Internal link** - Toggle on to set an internal link. For an internal link, you can select the target data source with a data source selector. This supports only tracing data sources. - -## Private data source connect (PDC) and Elasticsearch - -Use private data source connect (PDC) to connect to and query data within a secure network without opening that network to inbound traffic from Grafana Cloud. See [Private data source connect](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) for more information on how PDC works and [Configure Grafana private data source connect (PDC)](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-grafana-private-data-source-connect-pdc) for steps on setting up a PDC connection. - -If you use PDC with SIGv4 (AWS Signature Version 4 Authentication), the PDC agent must allow internet egress to`sts..amazonaws.com:443`. - -- **Private data source connect** - Click in the box to set the default PDC connection from the dropdown menu or create a new connection. - -Once you have configured your Elasticsearch data source options, click **Save & test** at the bottom to test out your data source connection. You can also remove a connection by clicking **Delete**. diff --git a/docs/sources/datasources/elasticsearch/configure/index.md b/docs/sources/datasources/elasticsearch/configure/index.md new file mode 100644 index 00000000000..d76a90855ea --- /dev/null +++ b/docs/sources/datasources/elasticsearch/configure/index.md @@ -0,0 +1,377 @@ +--- +aliases: + - ../configure-elasticsearch-data-source/ +description: Guide for configuring the Elasticsearch data source in Grafana +keywords: + - grafana + - elasticsearch + - guide + - data source +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Configure +title: Configure the Elasticsearch data source +weight: 200 +refs: + administration-documentation: + - pattern: /docs/grafana/ + destination: /docs/grafana//administration/data-source-management/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//administration/data-source-management/ + supported-expressions: + - pattern: /docs/grafana/ + destination: /docs/grafana//explore/logs-integration/#log-level + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//explore/logs-integration/#log-level + query-and-transform-data: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/query-transform-data/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/ + provisioning-data-source: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/elasticsearch/configure/#provision-the-data-source + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/connect-externally-hosted/data-sources/elasticsearch/configure/#provision-the-data-source + configuration: + - pattern: /docs/grafana/ + destination: /docs/grafana//setup-grafana/configure-grafana/#sigv4_auth_enabled + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//setup-grafana/configure-grafana/#sigv4_auth_enabled + provisioning-grafana: + - pattern: /docs/grafana/ + destination: /docs/grafana//administration/provisioning/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//administration/provisioning/ +--- + +# Configure the Elasticsearch data source + +Grafana ships with built-in support for Elasticsearch. +You can create a variety of queries to visualize logs or metrics stored in Elasticsearch, and annotate graphs with log events stored in Elasticsearch. + +For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref:administration-documentation). +Administrators can also [configure the data source via YAML](ref:provisioning-data-source) with Grafana's provisioning system. + +## Before you begin + +To configure the Elasticsearch data source, you need: + +- **Grafana administrator permissions:** Only users with the organization `administrator` role can add data sources. +- **A supported Elasticsearch version:** v7.17 or later, v8.x, or v9.x. Elastic Cloud Serverless isn't supported. +- **Elasticsearch server URL:** The HTTP or HTTPS endpoint for your Elasticsearch instance, including the port (default: `9200`). +- **Authentication credentials:** Depending on your Elasticsearch security configuration, you need one of the following: + - Username and password for basic authentication + - API key + - No credentials (if Elasticsearch security is disabled) +- **Network access:** Grafana must be able to reach your Elasticsearch server. For Grafana Cloud, consider using [Private data source connect (PDC)](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) if your Elasticsearch instance is in a private network. + +## Elasticsearch permissions + +When Elasticsearch security features are enabled, you must configure the following cluster privileges for the user or API key that Grafana uses to connect: + +- **monitor** - Necessary to retrieve the version information of the connected Elasticsearch instance. +- **view_index_metadata** - Required for accessing mapping definitions of indices. +- **read** - Grants the ability to perform search and retrieval operations on indices. This is essential for querying and extracting data from the cluster. + +## Add the data source + +To add the Elasticsearch data source, complete the following steps: + +1. Click **Connections** in the left-side menu. +1. Under **Connections**, click **Add new connection**. +1. Enter `Elasticsearch` in the search bar. +1. Click **Elasticsearch** under the **Data source** section. +1. Click **Add new data source** in the upper right. + +You will be taken to the **Settings** tab where you will set up your Elasticsearch configuration. + +## Configuration options + +Configure the following basic settings for the Elasticsearch data source: + +- **Name** - The data source name. This is how you refer to the data source in panels and queries. Examples: `elastic-1`, `elasticsearch_metrics`. + +- **Default** - Toggle on to make this the default data source. New panels and Explore queries use the default data source. + +## Connection + +- **URL** - The URL of your Elasticsearch server, including the port. Examples: `http://localhost:9200`, `http://elasticsearch.example.com:9200`. + +## Authentication + +Select an authentication method from the drop-down menu: + +- **Basic authentication** - Enter the username and password for your Elasticsearch user. + +- **Forward OAuth identity** - Forward the OAuth access token (and the OIDC ID token if available) of the user querying the data source. + +- **No authentication** - Connect without credentials. Only use this option if your Elasticsearch instance doesn't require authentication. + +### API key authentication + +To authenticate using an Elasticsearch API key, select **No authentication** and configure the API key using HTTP headers: + +1. In the **HTTP headers** section, click **+ Add header**. +1. Set **Header** to `Authorization`. +1. Set **Value** to `ApiKey `, replacing `` with your base64-encoded Elasticsearch API key. + +For information about creating API keys, refer to the [Elasticsearch API keys documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html). + +### Amazon Elasticsearch Service + +If you use Amazon Elasticsearch Service, you can use Grafana's Elasticsearch data source to visualize data from it. + +If you use an AWS Identity and Access Management (IAM) policy to control access to your Amazon Elasticsearch Service domain, you must use AWS Signature Version 4 (AWS SigV4) to sign all requests to that domain. + +For details on AWS SigV4, refer to the [AWS documentation](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html). + +To sign requests to your Amazon Elasticsearch Service domain, you can enable SigV4 in Grafana's [configuration](ref:configuration). + +Once AWS SigV4 is enabled, you can configure it on the Elasticsearch data source configuration page. +For more information about AWS authentication options, refer to [AWS authentication](https://grafana.com/docs/grafana//datasources/aws-cloudwatch/aws-authentication/). + +{{< figure src="/static/img/docs/v73/elasticsearch-sigv4-config-editor.png" max-width="500px" class="docs-image--no-shadow" caption="SigV4 configuration for AWS Elasticsearch Service" >}} + +### TLS settings + +{{< admonition type="note" >}} +Use TLS (Transport Layer Security) for an additional layer of security when working with Elasticsearch. For information on setting up TLS encryption with Elasticsearch, refer to [Configure TLS](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/configuring-tls.html#configuring-tls). You must add TLS settings to your Elasticsearch configuration file **prior** to setting these options in Grafana. +{{< /admonition >}} + +- **Add self-signed certificate** - Check the box to authenticate with a CA certificate. Follow the instructions of the CA (Certificate Authority) to download the certificate file. Required for verifying self-signed TLS certificates. + +- **TLS client authentication** - Check the box to authenticate with the TLS client, where the server authenticates the client. Add the `Server name`, `Client certificate` and `Client key`. The **ServerName** is used to verify the hostname on the returned certificate. The **Client certificate** can be generated from a Certificate Authority (CA) or be self-signed. The **Client key** can also be generated from a Certificate Authority (CA) or be self-signed. The client key encrypts the data between client and server. + +- **Skip TLS certificate validation** - Check the box to bypass TLS certificate validation. Skipping TLS certificate validation is not recommended unless absolutely necessary or for testing purposes. + +### HTTP headers + +Click **+ Add header** to add one or more HTTP headers. HTTP headers pass additional context and metadata about the request/response. + +- **Header** - Add a custom header. This allows custom headers to be passed based on the needs of your Elasticsearch instance. + +- **Value** - The value of the header. + +## Additional settings + +Additional settings are optional settings that can be configured for more control over your data source. + +### Advanced HTTP settings + +- **Allowed cookies** - Specify cookies by name that should be forwarded to the data source. The Grafana proxy deletes all forwarded cookies by default. + +- **Timeout** - The HTTP request timeout. This must be in seconds. There is no default, so this setting is up to you. + +### Elasticsearch details + +The following settings are specific to the Elasticsearch data source. + +- **Index name** - The name of your Elasticsearch index. You can use the following formats: + - **Wildcard patterns** - Use `*` to match multiple indices. Examples: `logs-*`, `metrics-*`, `filebeat-*`. + - **Time patterns** - Use date placeholders for time-based indices. Wrap the fixed portion in square brackets. Examples: `[logstash-]YYYY.MM.DD`, `[metrics-]YYYY.MM`. + - **Specific index** - Enter the exact index name. Example: `application-logs`. + +- **Pattern** - Select the matching pattern if you use a time pattern in your index name. Options include: + - no pattern + - hourly + - daily + - weekly + - monthly + - yearly + +Only select a pattern option if you have specified a time pattern in the Index name field. + +- **Time field name** - Name of the time field. The default value is `@timestamp`. You can enter a different name. + +- **Max concurrent shard requests** - Sets the number of shards being queried at the same time. The default is `5`. For more information on shards, refer to the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/scalability.html#scalability). + +- **Min time interval** - Defines a lower limit for the auto group-by time interval. This value **must** be formatted as a number followed by a valid time identifier: + + | Identifier | Description | + | ---------- | ----------- | + | `y` | year | + | `M` | month | + | `w` | week | + | `d` | day | + | `h` | hour | + | `m` | minute | + | `s` | second | + | `ms` | millisecond | + +We recommend setting this value to match your Elasticsearch write frequency. +For example, set this to `1m` if Elasticsearch writes data every minute. + +You can also override this setting in a dashboard panel under its data source options. The default is `10s`. + +- **X-Pack enabled** - Toggle to enable `X-Pack`-specific features and options, which provide the [query editor](https://grafana.com/docs/grafana//datasources/elasticsearch/query-editor/) with additional aggregations, such as `Rate` and `Top Metrics`. + +- **Include frozen indices** - Toggle on when the `X-Pack enabled` setting is active. Includes frozen indices in searches. You can configure Grafana to include [frozen indices](https://www.elastic.co/guide/en/elasticsearch/reference/7.13/frozen-indices.html) when performing search requests. + +{{< admonition type="note" >}} +Frozen indices are [deprecated in Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/frozen-indices.html) since v7.14. +{{< /admonition >}} + +### Logs + +Configure which fields the data source uses for log messages and log levels. + +- **Message field name** - The field that contains the log message content. + +- **Level field name** - The field that contains log level or severity information. When specified, Grafana uses this field to determine the log level and color-code each log line. If the log doesn't have a level field, Grafana tries to match the content against [supported expressions](ref:supported-expressions). If Grafana can't determine the log level, it displays as unknown. + +### Data links + +Data links create a link from a specified field that can be accessed in Explore's logs view. You can add multiple data links by clicking **+ Add**. + +Each data link configuration consists of: + +- **Field** - Sets the name of the field used by the data link. + +- **URL/query** - Sets the full link URL if the link is external. If the link is internal, this input serves as a query for the target data source.
In both cases, you can interpolate the value from the field with the `${__value.raw }` macro. + +- **URL Label** (Optional) - Sets a custom display label for the link. The link label defaults to the full external URL or name of the linked internal data source and is overridden by this setting. + +- **Internal link** - Toggle on to set an internal link. For an internal link, you can select the target data source with a data source selector. This supports only tracing data sources. + +## Private data source connect (PDC) and Elasticsearch + +Use private data source connect (PDC) to connect to and query data within a secure network without opening that network to inbound traffic from Grafana Cloud. Refer to [Private data source connect](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) for more information on how PDC works and [Configure Grafana private data source connect (PDC)](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-grafana-private-data-source-connect-pdc) for steps on setting up a PDC connection. + +If you use PDC with SigV4 (AWS Signature Version 4 Authentication), the PDC agent must allow internet egress to `sts..amazonaws.com:443`. + +- **Private data source connect** - Click in the box to set the default PDC connection from the drop-down menu or create a new connection. + +Once you have configured your Elasticsearch data source options, click **Save & test** to test the connection. A successful connection displays the following message: + +`Elasticsearch data source is healthy.` + +## Provision the data source + +You can define and configure the data source in YAML files as part of Grafana's provisioning system. +For more information about provisioning, and for available configuration options, refer to [Provisioning Grafana](ref:provisioning-grafana). + +{{< admonition type="note" >}} +The previously used `database` field has now been [deprecated](https://github.com/grafana/grafana/pull/58647). +Use the `index` field in `jsonData` to store the index name. +Refer to the examples below. +{{< /admonition >}} + +### Basic provisioning + +```yaml +apiVersion: 1 + +datasources: + - name: Elastic + type: elasticsearch + access: proxy + url: http://localhost:9200 + jsonData: + index: '[metrics-]YYYY.MM.DD' + interval: Daily + timeField: '@timestamp' +``` + +### Provision for logs + +```yaml +apiVersion: 1 + +datasources: + - name: elasticsearch-v7-filebeat + type: elasticsearch + access: proxy + url: http://localhost:9200 + jsonData: + index: '[filebeat-]YYYY.MM.DD' + interval: Daily + timeField: '@timestamp' + logMessageField: message + logLevelField: fields.level + dataLinks: + - datasourceUid: my_jaeger_uid # Target UID needs to be known + field: traceID + url: '$${__value.raw}' # Careful about the double "$$" because of env var expansion +``` + +## Provision the data source using Terraform + +You can provision the Elasticsearch data source using [Terraform](https://www.terraform.io/) with the [Grafana Terraform provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs). + +For more information about provisioning resources with Terraform, refer to the [Grafana as code using Terraform](https://grafana.com/docs/grafana-cloud/developer-resources/infrastructure-as-code/terraform/) documentation. + +### Basic Terraform example + +The following example creates a basic Elasticsearch data source for metrics: + +```hcl +resource "grafana_data_source" "elasticsearch" { + name = "Elasticsearch" + type = "elasticsearch" + url = "http://localhost:9200" + + json_data_encoded = jsonencode({ + index = "[metrics-]YYYY.MM.DD" + interval = "Daily" + timeField = "@timestamp" + }) +} +``` + +### Terraform example for logs + +The following example creates an Elasticsearch data source configured for logs with a data link to Jaeger: + +```hcl +resource "grafana_data_source" "elasticsearch_logs" { + name = "Elasticsearch Logs" + type = "elasticsearch" + url = "http://localhost:9200" + + json_data_encoded = jsonencode({ + index = "[filebeat-]YYYY.MM.DD" + interval = "Daily" + timeField = "@timestamp" + logMessageField = "message" + logLevelField = "fields.level" + dataLinks = [ + { + datasourceUid = grafana_data_source.jaeger.uid + field = "traceID" + url = "$${__value.raw}" + } + ] + }) +} +``` + +### Terraform example with basic authentication + +The following example includes basic authentication: + +```hcl +resource "grafana_data_source" "elasticsearch_auth" { + name = "Elasticsearch" + type = "elasticsearch" + url = "http://localhost:9200" + + basic_auth_enabled = true + basic_auth_username = "elastic_user" + + secure_json_data_encoded = jsonencode({ + basicAuthPassword = var.elasticsearch_password + }) + + json_data_encoded = jsonencode({ + index = "[metrics-]YYYY.MM.DD" + interval = "Daily" + timeField = "@timestamp" + }) +} +``` + +For all available configuration options, refer to the [Grafana provider data source resource documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source). diff --git a/docs/sources/datasources/elasticsearch/query-editor/index.md b/docs/sources/datasources/elasticsearch/query-editor/index.md index fa20353a395..c5c7bf91abf 100644 --- a/docs/sources/datasources/elasticsearch/query-editor/index.md +++ b/docs/sources/datasources/elasticsearch/query-editor/index.md @@ -30,7 +30,7 @@ refs: # Elasticsearch query editor Grafana provides a query editor for Elasticsearch. Elasticsearch queries are in Lucene format. -See [Lucene query syntax](https://www.elastic.co/guide/en/kibana/current/lucene-query.html) and [Query string syntax](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/query-dsl-query-string-query.html#query-string-syntax) if you are new to working with Lucene queries in Elasticsearch. +For more information about query syntax, refer to [Lucene query syntax](https://www.elastic.co/guide/en/kibana/current/lucene-query.html) and [Query string syntax](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax). {{< admonition type="note" >}} When composing Lucene queries, ensure that you use uppercase boolean operators: `AND`, `OR`, and `NOT`. Lowercase versions of these operators are not supported by the Lucene query syntax. @@ -38,17 +38,17 @@ When composing Lucene queries, ensure that you use uppercase boolean operators: {{< figure src="/static/img/docs/elasticsearch/elastic-query-editor-10.1.png" max-width="800px" class="docs-image--no-shadow" caption="Elasticsearch query editor" >}} -For general documentation on querying data sources in Grafana, including options and functions common to all query editors, see [Query and transform data](ref:query-and-transform-data). +For general documentation on querying data sources in Grafana, including options and functions common to all query editors, refer to [Query and transform data](ref:query-and-transform-data). ## Aggregation types Elasticsearch groups aggregations into three categories: -- **Bucket** - Bucket aggregations don't calculate metrics, they create buckets of documents based on field values, ranges and a variety of other criteria. See [Bucket aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket.html) for additional information. Use bucket aggregations under `Group by` when creating a metrics query in the query builder. +- **Bucket** - Bucket aggregations don't calculate metrics, they create buckets of documents based on field values, ranges and a variety of other criteria. Refer to [Bucket aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket.html) for additional information. Use bucket aggregations under `Group by` when creating a metrics query in the query builder. -- **Metrics** - Metrics aggregations perform calculations such as sum, average, min, etc. They can be single-value or multi-value. See [Metrics aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics.html) for additional information. Use metrics aggregations in the metrics query type in the query builder. +- **Metrics** - Metrics aggregations perform calculations such as sum, average, min, etc. They can be single-value or multi-value. Refer to [Metrics aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics.html) for additional information. Use metrics aggregations in the metrics query type in the query builder. -- **Pipeline** - Elasticsearch pipeline aggregations work with inputs or metrics created from other aggregations (not documents or fields). There are parent and sibling and sibling pipeline aggregations. See [Pipeline aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-pipeline.html) for additional information. +- **Pipeline** - Pipeline aggregations work on the output of other aggregations rather than on documents or fields. Refer to [Pipeline aggregations](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline.html) for additional information. ## Select a query type @@ -56,44 +56,51 @@ There are three types of queries you can create with the Elasticsearch query bui ### Metrics query type -Metrics queries aggregate data and produce a variety of calculations such as count, min, max, etc. Click on the metric box to view a list of options in the dropdown menu. The default is `count`. +Metrics queries aggregate data and produce calculations such as count, min, max, and more. Click the metric box to view options in the drop-down menu. The default is `count`. - **Alias** - Aliasing only applies to **time series queries**, where the last group is `date histogram`. This is ignored for any other type of query. - **Metric** - Metrics aggregations include: - - count - see [Value count aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-valuecount-aggregation.html) - - average - see [Avg aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-rate-aggregation.html) - - sum - see [Sum aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html) - - max - see [Max aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-max-aggregation.html) - - min - see [Min aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-min-aggregation.html) - - extended stats - see [Extended stats aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html) - - percentiles - see [Percentiles aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-percentile-aggregation.html) - - unique count - see [Cardinality aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-cardinality-aggregation.html) - - top metrics - see [Top metrics aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-top-metrics.html) - - rate - see [Rate aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/8.9/search-aggregations-metrics-rate-aggregation.html) + - count - refer to [Value count aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-valuecount-aggregation.html) + - average - refer to [Avg aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-avg-aggregation.html) + - sum - refer to [Sum aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-sum-aggregation.html) + - max - refer to [Max aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-max-aggregation.html) + - min - refer to [Min aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-min-aggregation.html) + - extended stats - refer to [Extended stats aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-extendedstats-aggregation.html) + - percentiles - refer to [Percentiles aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-percentile-aggregation.html) + - unique count - refer to [Cardinality aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html) + - top metrics - refer to [Top metrics aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-top-metrics.html) + - rate - refer to [Rate aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-rate-aggregation.html) + +- **Pipeline aggregations** - Pipeline aggregations work on the output of other aggregations rather than on documents. The following pipeline aggregations are available: + - moving function - Calculates a value based on a sliding window of aggregated values. Refer to [Moving function aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-movfn-aggregation.html). + - derivative - Calculates the derivative of a metric. Refer to [Derivative aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-derivative-aggregation.html). + - cumulative sum - Calculates the cumulative sum of a metric. Refer to [Cumulative sum aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-cumulative-sum-aggregation.html). + - serial difference - Calculates the difference between values in a time series. Refer to [Serial differencing aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-serialdiff-aggregation.html). + - bucket script - Executes a script on metric values from other aggregations. Refer to [Bucket script aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-script-aggregation.html). You can select multiple metrics and group by multiple terms or filters when using the Elasticsearch query editor. Use the **+ sign** to the right to add multiple metrics to your query. Click on the **eye icon** next to **Metric** to hide metrics, and the **garbage can icon** to remove metrics. -- **Group by options** - Create multiple group by options when constructing your Elasticsearch query. Date histogram is the default option. Below is a list of options in the dropdown menu. - - terms - see [Terms aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html). - - filter - see [Filter aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html). - - geo hash grid - see [Geohash grid aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html). - - date histogram - for time series queries. See [Date histogram aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html). - - histogram - Depicts frequency distributions. See [Histogram aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html). - - nested (experimental) - See [Nested aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html). +- **Group by options** - Create multiple group by options when constructing your Elasticsearch query. Date histogram is the default option. The following options are available in the drop-down menu: + - terms - refer to [Terms aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html). + - filter - refer to [Filter aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html). + - geo hash grid - refer to [Geohash grid aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html). + - date histogram - for time series queries. Refer to [Date histogram aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-datehistogram-aggregation.html). + - histogram - Depicts frequency distributions. Refer to [Histogram aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-histogram-aggregation.html). + - nested (experimental) - Refer to [Nested aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html). Each group by option will have a different subset of options to further narrow your query. The following options are specific to the **date histogram** bucket aggregation option. -- **Time field** - Depicts date data options. The default option can be specified when configuring the Elasticsearch data source in the **Time field name** under the [**Elasticsearch details**](/docs/grafana/latest/datasources/elasticsearch/configure-elasticsearch-data-source/#elasticsearch-details) section. Otherwise **@timestamp** field will be used as a default option. -- **Interval** - Group by a type of interval. There are option to choose from the dropdown menu to select seconds, minutes, hours or day. You can also add a custom interval such as `30d` (30 days). `Auto` is the default option. -- **Min doc count** - The minimum amount of data to include in your query. The default is `0`. -- **Thin edges** - Select to trim edges on the time series data points. The default is `0`. -- **Offset** - Changes the start value of each bucket by the specified positive(+) or negative (-) offset duration. Examples include `1h` for 1 hour, `5s` for 5 seconds or `1d` for 1 day. -- **Timezone** - Select a timezone from the dropdown menu. The default is `Coordinated universal time`. +- **Time field** - The field used for time-based queries. The default can be set when configuring the data source in the **Time field name** setting under [Elasticsearch details](https://grafana.com/docs/grafana//datasources/elasticsearch/configure/#elasticsearch-details). The default is `@timestamp`. +- **Interval** - The time interval for grouping data. Select from the drop-down menu or enter a custom interval such as `30d` (30 days). The default is `Auto`. +- **Min doc count** - The minimum number of documents required to include a bucket. The default is `0`. +- **Trim edges** - Removes partial buckets at the edges of the time range. The default is `0`. +- **Offset** - Shifts the start of each bucket by the specified duration. Use positive (`+`) or negative (`-`) values. Examples: `1h`, `5s`, `1d`. +- **Timezone** - The timezone for date calculations. The default is `Coordinated Universal Time`. Configure the following options for the **terms** bucket aggregation option: @@ -101,7 +108,7 @@ Configure the following options for the **terms** bucket aggregation option: - **Size** - Limits the number of documents, or size of the data set. You can set a custom number or `no limit`. - **Min doc count** - The minimum amount of data to include in your query. The default is `0`. - **Order by** - Order terms by `term value`, `doc count` or `count`. -- **Missing** - Defines how documents missing a value should be treated. Missing values are ignored by default, but they can be treated as if they had a value. See [Missing value](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_missing_value_5) in Elasticsearch's documentation for more information. +- **Missing** - Defines how documents missing a value should be treated. Missing values are ignored by default, but they can be treated as if they had a value. Refer to [Missing value](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_missing_value_5) in the Elasticsearch documentation for more information. Configure the following options for the **filters** bucket aggregation option: @@ -114,8 +121,8 @@ Configure the following options for the **geo hash grid** bucket aggregation opt Configure the following options for the **histogram** bucket aggregation option: -- **Interval** - Group by a type of interval. There are option to choose from the dropdown menu to select seconds, minutes, hours or day. You can also add a custom interval such as `30d` (30 days). `Auto` is the default option. -- **Min doc count** - The minimum amount of data to include in your query. The default is `0` +- **Interval** - The numeric interval for grouping values into buckets. +- **Min doc count** - The minimum number of documents required to include a bucket. The default is `0`. The **nested** group by option is currently experimental, you can select a field and then settings specific to that field. @@ -141,7 +148,7 @@ The option to run a **raw document query** is deprecated as of Grafana v10.1. ## Use template variables -You can also augment queries by using [template variables](../template-variables/). +You can also augment queries by using [template variables](https://grafana.com/docs/grafana//datasources/elasticsearch/template-variables/). Queries of `terms` have a 500-result limit by default. To set a custom limit, set the `size` property in your query. diff --git a/docs/sources/datasources/elasticsearch/template-variables/index.md b/docs/sources/datasources/elasticsearch/template-variables/index.md index 66ca17a93bd..ed2cb95f3af 100644 --- a/docs/sources/datasources/elasticsearch/template-variables/index.md +++ b/docs/sources/datasources/elasticsearch/template-variables/index.md @@ -22,6 +22,11 @@ refs: destination: /docs/grafana//dashboards/variables/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//dashboards/variables/ + add-template-variables-add-ad-hoc-filters: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#add-ad-hoc-filters + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#add-ad-hoc-filters add-template-variables-multi-value-variables: - pattern: /docs/grafana/ destination: /docs/grafana//dashboards/variables/add-template-variables/#multi-value-variables @@ -37,11 +42,29 @@ refs: # Elasticsearch template variables Instead of hard-coding details such as server, application, and sensor names in metric queries, you can use variables. -Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. +Grafana lists these variables in drop-down select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. For an introduction to templating and template variables, refer to the [Templating](ref:variables) and [Add and manage variables](ref:add-template-variables) documentation. +## Use ad hoc filters + +Elasticsearch supports the **Ad hoc filters** variable type. +You can use this variable type to specify any number of key/value filters, and Grafana applies them automatically to all of your Elasticsearch queries. + +Ad hoc filters support the following operators: + +| Operator | Description | +| -------- | ------------------------------------------------------------- | +| `=` | Equals. Adds `AND field:"value"` to the query. | +| `!=` | Not equals. Adds `AND -field:"value"` to the query. | +| `=~` | Matches regex. Adds `AND field:/value/` to the query. | +| `!~` | Does not match regex. Adds `AND -field:/value/` to the query. | +| `>` | Greater than. Adds `AND field:>value` to the query. | +| `<` | Less than. Adds `AND field:}} -To use an ascending sort (`asc`) with doc_count (a bottom-N list), set `order: "asc"`. However, Elasticsearch [discourages this](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-order) because sorting by ascending doc count can return inaccurate results. -{{< /admonition >}} - -To keep terms in the doc count order, set the variable's Sort dropdown to **Disabled**. -You can alternatively use other sorting criteria, such as **Alphabetical**, to re-sort them. +This example defines a variable named `$host` that only shows hosts matching the selected `$environment`: +```json +{ "find": "terms", "field": "hostname", "query": "environment:$environment" } ``` -{"find": "terms", "field": "hostname", "orderBy": "doc_count"} -``` + +Whenever you change the value of the `$environment` variable via the drop-down, Grafana triggers an update of the `$host` variable to contain only hostnames filtered by the selected environment. + +### Variables in aggregations + +You can use variables in bucket aggregation fields to dynamically change how data is grouped. For example, use a variable in the **Terms** group by field to let users switch between grouping by `hostname`, `service`, or `datacenter`. ## Template variable examples @@ -92,11 +116,36 @@ Write the query using a custom JSON string, with the field mapped as a [keyword] If the query is [multi-field](https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html) with both a `text` and `keyword` type, use `"field":"fieldname.keyword"` (sometimes `fieldname.raw`) to specify the keyword field in your query. -| Query | Description | -| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `{"find": "fields", "type": "keyword"}` | Returns a list of field names with the index type `keyword`. | -| `{"find": "terms", "field": "hostname.keyword", "size": 1000}` | Returns a list of values for a keyword using term aggregation. Query will use current dashboard time range as time range query. | -| `{"find": "terms", "field": "hostname", "query": ''}` | Returns a list of values for a keyword field using term aggregation and a specified Lucene query filter. Query will use current dashboard time range as time range for query. | +| Query | Description | +| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | +| `{"find": "fields", "type": "keyword"}` | Returns a list of field names with the index type `keyword`. | +| `{"find": "fields", "type": "number"}` | Returns a list of numeric field names (includes `float`, `double`, `integer`, `long`, `scaled_float`). | +| `{"find": "fields", "type": "date"}` | Returns a list of date field names. | +| `{"find": "terms", "field": "hostname.keyword", "size": 1000}` | Returns a list of values for a keyword field. Uses the current dashboard time range. | +| `{"find": "terms", "field": "hostname", "query": ""}` | Returns a list of values filtered by a Lucene query. Uses the current dashboard time range. | +| `{"find": "terms", "field": "status", "orderBy": "doc_count"}` | Returns values sorted by document count (descending by default). | +| `{"find": "terms", "field": "status", "orderBy": "doc_count", "order": "asc"}` | Returns values sorted by document count in ascending order. | -Queries of `terms` have a 500-result limit by default. -To set a custom limit, set the `size` property in your query. +Queries of `terms` have a 500-result limit by default. To set a custom limit, set the `size` property in your query. + +### Sort query results + +By default, queries return results in term order (which can then be sorted alphabetically or numerically using the variable's Sort setting). + +To produce a list of terms sorted by document count (a top-N values list), add an `orderBy` property of `doc_count`. This automatically selects a descending sort: + +```json +{ "find": "terms", "field": "status", "orderBy": "doc_count" } +``` + +You can also use the `order` property to explicitly set ascending or descending sort: + +```json +{ "find": "terms", "field": "hostname", "orderBy": "doc_count", "order": "asc" } +``` + +{{< admonition type="note" >}} +Elasticsearch [discourages](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-order) sorting by ascending doc count because it can return inaccurate results. +{{< /admonition >}} + +To keep terms in the document count order, set the variable's Sort drop-down to **Disabled**. You can alternatively use other sorting criteria, such as **Alphabetical**, to re-sort them. diff --git a/docs/sources/datasources/elasticsearch/troubleshooting/index.md b/docs/sources/datasources/elasticsearch/troubleshooting/index.md new file mode 100644 index 00000000000..ff0f73c6093 --- /dev/null +++ b/docs/sources/datasources/elasticsearch/troubleshooting/index.md @@ -0,0 +1,266 @@ +--- +aliases: + - ../../data-sources/elasticsearch/troubleshooting/ +description: Troubleshooting the Elasticsearch data source in Grafana +keywords: + - grafana + - elasticsearch + - troubleshooting + - errors +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Troubleshooting +title: Troubleshoot issues with the Elasticsearch data source +weight: 600 +--- + +# Troubleshoot issues with the Elasticsearch data source + +This document provides troubleshooting information for common errors you may encounter when using the Elasticsearch data source in Grafana. + +## Connection errors + +The following errors occur when Grafana cannot establish or maintain a connection to Elasticsearch. + +### Failed to connect to Elasticsearch + +**Error message:** "Health check failed: Failed to connect to Elasticsearch" + +**Cause:** Grafana cannot establish a network connection to the Elasticsearch server. + +**Solution:** + +1. Verify that the Elasticsearch URL is correct in the data source configuration. +1. Check that Elasticsearch is running and accessible from the Grafana server. +1. Ensure there are no firewall rules blocking the connection. +1. If using a proxy, verify the proxy settings are correct. +1. For Grafana Cloud, ensure you have configured [Private data source connect](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) if your Elasticsearch instance is not publicly accessible. + +### Request timed out + +**Error message:** "Health check failed: Elasticsearch data source is not healthy. Request timed out" + +**Cause:** The connection to Elasticsearch timed out before receiving a response. + +**Solution:** + +1. Check the network latency between Grafana and Elasticsearch. +1. Verify that Elasticsearch is not overloaded or experiencing performance issues. +1. Increase the timeout setting in the data source configuration if needed. +1. Check if any network devices (load balancers, proxies) are timing out the connection. + +### Failed to parse data source URL + +**Error message:** "Failed to parse data source URL" + +**Cause:** The URL entered in the data source configuration is not valid. + +**Solution:** + +1. Verify the URL format is correct (for example, `http://localhost:9200` or `https://elasticsearch.example.com:9200`). +1. Ensure the URL includes the protocol (`http://` or `https://`). +1. Remove any trailing slashes or invalid characters from the URL. + +## Authentication errors + +The following errors occur when there are issues with authentication credentials or permissions. + +### Unauthorized (401) + +**Error message:** "Health check failed: Elasticsearch data source is not healthy. Status: 401 Unauthorized" + +**Cause:** The authentication credentials are invalid or missing. + +**Solution:** + +1. Verify that the username and password are correct. +1. If using an API key, ensure the key is valid and has not expired. +1. Check that the authentication method selected matches your Elasticsearch configuration. +1. Verify the user has the required permissions to access the Elasticsearch cluster. + +### Forbidden (403) + +**Error message:** "Health check failed: Elasticsearch data source is not healthy. Status: 403 Forbidden" + +**Cause:** The authenticated user does not have permission to access the requested resource. + +**Solution:** + +1. Verify the user has read access to the specified index. +1. Check Elasticsearch security settings and role mappings. +1. Ensure the user has permission to access the `_cluster/health` endpoint. +1. If using AWS Elasticsearch Service with SigV4 authentication, verify the IAM policy grants the required permissions. + +## Cluster health errors + +The following errors occur when the Elasticsearch cluster is unhealthy or unavailable. + +### Cluster status is red + +**Error message:** "Health check failed: Elasticsearch data source is not healthy" + +**Cause:** The Elasticsearch cluster health status is red, indicating one or more primary shards are not allocated. + +**Solution:** + +1. Check the Elasticsearch cluster health using `GET /_cluster/health`. +1. Review Elasticsearch logs for errors. +1. Verify all nodes in the cluster are running and connected. +1. Check for unassigned shards using `GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason`. +1. Consider increasing the cluster's resources or reducing the number of shards. + +### Bad Gateway (502) + +**Error message:** "Health check failed: Elasticsearch data source is not healthy. Status: 502 Bad Gateway" + +**Cause:** A proxy or load balancer between Grafana and Elasticsearch returned an error. + +**Solution:** + +1. Check the health of any proxies or load balancers in the connection path. +1. Verify Elasticsearch is running and accepting connections. +1. Review proxy/load balancer logs for more details. +1. Ensure the proxy timeout is configured appropriately for Elasticsearch requests. + +## Index errors + +The following errors occur when there are issues with the configured index or index pattern. + +### Index not found + +**Error message:** "Error validating index: index_not_found" + +**Cause:** The specified index or index pattern does not match any existing indices. + +**Solution:** + +1. Verify the index name or pattern in the data source configuration. +1. Check that the index exists using `GET /_cat/indices`. +1. If using a time-based index pattern (for example, `[logs-]YYYY.MM.DD`), ensure indices exist for the selected time range. +1. Verify the user has permission to access the index. + +### Time field not found + +**Error message:** "Could not find time field '@timestamp' with type date in index" + +**Cause:** The specified time field does not exist in the index or is not of type `date`. + +**Solution:** + +1. Verify the time field name in the data source configuration matches the field in your index. +1. Check the field mapping using `GET //_mapping`. +1. Ensure the time field is mapped as a `date` type, not `text` or `keyword`. +1. If the field name is different (for example, `timestamp` instead of `@timestamp`), update the data source configuration. + +## Query errors + +The following errors occur when there are issues with query syntax or configuration. + +### Too many buckets + +**Error message:** "Trying to create too many buckets. Must be less than or equal to: [65536]." + +**Cause:** The query is generating more aggregation buckets than Elasticsearch allows. + +**Solution:** + +1. Reduce the time range of your query. +1. Increase the date histogram interval (for example, change from `10s` to `1m`). +1. Add filters to reduce the number of documents being aggregated. +1. Increase the `search.max_buckets` setting in Elasticsearch (requires cluster admin access). + +### Required field missing + +**Error message:** "Required one of fields [field, script], but none were specified." + +**Cause:** A metric aggregation (such as Average, Sum, or Min) was added without specifying a field. + +**Solution:** + +1. Select a field for the metric aggregation in the query editor. +1. Ensure the selected field exists in your index and contains numeric data. + +### Unsupported interval + +**Error message:** "unsupported interval '<interval>'" + +**Cause:** The interval specified for the index pattern is not valid. + +**Solution:** + +1. Use a supported interval: `Hourly`, `Daily`, `Weekly`, `Monthly`, or `Yearly`. +1. If you don't need a time-based index pattern, use `No pattern` and specify the exact index name. + +## Version errors + +The following errors occur when there are Elasticsearch version compatibility issues. + +### Unsupported Elasticsearch version + +**Error message:** "Support for Elasticsearch versions after their end-of-life (currently versions < 7.16) was removed. Using unsupported version of Elasticsearch may lead to unexpected and incorrect results." + +**Cause:** The Elasticsearch version is no longer supported by the Grafana data source. + +**Solution:** + +1. Upgrade Elasticsearch to a supported version (7.17+, 8.x, or 9.x). +1. Refer to [Elastic Product End of Life Dates](https://www.elastic.co/support/eol) for version support information. +1. Note that queries may still work, but Grafana does not guarantee functionality for unsupported versions. + +## Other common issues + +The following issues don't produce specific error messages but are commonly encountered. + +### Empty query results + +**Cause:** The query returns no data. + +**Solution:** + +1. Verify the time range includes data in your index. +1. Check the Lucene query syntax for errors. +1. Test the query directly in Elasticsearch using the `_search` API. +1. Ensure the index contains documents matching your query filters. + +### Slow query performance + +**Cause:** Queries take a long time to execute. + +**Solution:** + +1. Reduce the time range of your query. +1. Add more specific filters to limit the data scanned. +1. Increase the date histogram interval. +1. Check Elasticsearch cluster performance and resource utilization. +1. Consider using index aliases or data streams for better query routing. + +### CORS errors in browser console + +**Cause:** Cross-Origin Resource Sharing (CORS) is blocking requests from the browser to Elasticsearch. + +**Solution:** + +1. Use Server (proxy) access mode instead of Browser access mode in the data source configuration. +1. If Browser access is required, configure CORS settings in Elasticsearch: + +```yaml +http.cors.enabled: true +http.cors.allow-origin: '' +http.cors.allow-headers: 'Authorization, Content-Type' +http.cors.allow-credentials: true +``` + +{{< admonition type="note" >}} +Server (proxy) access mode is recommended for security and reliability. +{{< /admonition >}} + +## Get additional help + +If you continue to experience issues after following this troubleshooting guide: + +1. Check the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html) for API-specific guidance. +1. Review the [Grafana community forums](https://community.grafana.com/) for similar issues. +1. Contact Grafana Support if you have an Enterprise license. diff --git a/docs/sources/datasources/graphite/_index.md b/docs/sources/datasources/graphite/_index.md index fba9d616f38..78972af5781 100644 --- a/docs/sources/datasources/graphite/_index.md +++ b/docs/sources/datasources/graphite/_index.md @@ -111,3 +111,4 @@ After installing and configuring the Graphite data source you can: - Add [transformations](ref:transformations) - Add [annotations](ref:annotate-visualizations) - Set up [alerting](ref:alerting) +- [Troubleshoot](troubleshooting/) common issues with the Graphite data source diff --git a/docs/sources/datasources/graphite/troubleshooting/index.md b/docs/sources/datasources/graphite/troubleshooting/index.md new file mode 100644 index 00000000000..41702c6b975 --- /dev/null +++ b/docs/sources/datasources/graphite/troubleshooting/index.md @@ -0,0 +1,174 @@ +--- +description: Troubleshoot common issues with the Graphite data source. +keywords: + - grafana + - graphite + - troubleshooting + - guide +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Troubleshooting +title: Troubleshoot Graphite data source issues +weight: 400 +refs: + configure-graphite: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/graphite/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/graphite/configure/ + query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/graphite/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/graphite/query-editor/ +--- + +# Troubleshoot Graphite data source issues + +This document provides solutions for common issues you might encounter when using the Graphite data source. + +## Connection issues + +Use the following troubleshooting steps to resolve connection problems between Grafana and your Graphite server. + +**Data source test fails with "Unable to connect":** + +If the data source test fails, verify the following: + +- The URL in your data source configuration is correct and accessible from the Grafana server. +- The Graphite server is running and accepting connections. +- Any firewall rules or network policies allow traffic between Grafana and the Graphite server. +- If using TLS, ensure your certificates are valid and properly configured. + +To test connectivity, run the following command from the Grafana server: + +```sh +curl -v /render +``` + +Replace _``_ with your Graphite server URL. A successful connection returns a response from the Graphite server. + +**Authentication errors:** + +If you receive 401 or 403 errors: + +- Verify your Basic Auth username and password are correct. +- Ensure the **With Credentials** toggle is enabled if your Graphite server requires cookies for authentication. +- Check that your TLS client certificates are valid and match what the server expects. + +For detailed authentication configuration, refer to [Configure the Graphite data source](ref:configure-graphite). + +## Query issues + +Use the following troubleshooting steps to resolve problems with Graphite queries. + +**No data returned:** + +If your query returns no data: + +- Verify the metric path exists in your Graphite server by testing directly in the Graphite web interface. +- Check that the time range in Grafana matches when data was collected. +- Ensure wildcards in your query match existing metrics. +- Confirm your query syntax is correct for your Graphite version. + +**HTTP 500 errors with HTML content:** + +Graphite-web versions before 1.6 return HTTP 500 errors with full HTML stack traces when a query fails. If you see error messages containing HTML tags: + +- Check the Graphite server logs for the full error details. +- Verify your query syntax is valid. +- Ensure the requested time range doesn't exceed your Graphite server's capabilities. +- Check that all functions used in your query are supported by your Graphite version. + +**Parser errors in the query editor:** + +If the query editor displays parser errors: + +- Check for unbalanced parentheses in function calls. +- Verify that function arguments are in the correct format. +- Ensure metric paths don't contain unsupported characters. + +For query syntax help, refer to [Graphite query editor](ref:query-editor). + +## Version and feature issues + +Use the following troubleshooting steps to resolve problems related to Graphite versions and features. + +**Functions missing from the query editor:** + +If expected functions don't appear in the query editor: + +- Verify the correct Graphite version is selected in the data source configuration. +- The available functions depend on the configured version. For example, tag-based functions require Graphite 1.1 or later. +- If using a custom Graphite installation with additional functions, ensure the version setting matches your server. + +**Tag-based queries not working:** + +If `seriesByTag()` or other tag functions fail: + +- Confirm your Graphite server is version 1.1 or later. +- Verify the Graphite version setting in your data source configuration matches your actual server version. +- Check that tags are properly configured in your Graphite server. + +## Performance issues + +Use the following troubleshooting steps to address slow queries or timeouts. + +**Queries timing out:** + +If queries consistently time out: + +- Increase the **Timeout** setting in the data source configuration. +- Reduce the time range of your query. +- Use more specific metric paths instead of broad wildcards. +- Consider using `summarize()` or `consolidateBy()` functions to reduce the amount of data returned. +- Check your Graphite server's performance and resource utilization. + +**Slow autocomplete in the query editor:** + +If metric path autocomplete is slow: + +- This often indicates a large number of metrics in your Graphite server. +- Use more specific path prefixes to narrow the search scope. +- Check your Graphite server's index performance. + +## MetricTank-specific issues + +If you're using MetricTank as your Graphite backend, use the following troubleshooting steps. + +**Rollup indicator not appearing:** + +If the rollup indicator doesn't display when expected: + +- Verify **Metrictank** is selected as the Graphite backend type in the data source configuration. +- Ensure the **Rollup indicator** toggle is enabled. +- The indicator only appears when data aggregation actually occurs. + +**Unexpected data aggregation:** + +If you see unexpected aggregation in your data: + +- Check the rollup configuration in your MetricTank instance. +- Adjust the time range or use `consolidateBy()` to control aggregation behavior. +- Review the query processing metadata in the panel inspector for details on how data was processed. + +## Get additional help + +If you continue to experience issues: + +- Check the [Grafana community forums](https://community.grafana.com/) for similar issues and solutions. +- Review the [Graphite documentation](https://graphite.readthedocs.io/) for additional configuration options. +- Contact [Grafana Support](https://grafana.com/support/) if you're an Enterprise, Cloud Pro, or Cloud Advanced customer. + +When reporting issues, include the following information: + +- Grafana version +- Graphite version (for example, 1.1.x) and backend type (Default or MetricTank) +- Authentication method (Basic Auth, TLS, or none) +- Error messages (redact sensitive information) +- Steps to reproduce the issue +- Relevant configuration such as data source settings, timeout values, and Graphite version setting (redact passwords and other credentials) +- Sample query (if applicable, with sensitive data redacted) diff --git a/docs/sources/datasources/influxdb/_index.md b/docs/sources/datasources/influxdb/_index.md index c3f722d848f..4ede6c02c52 100644 --- a/docs/sources/datasources/influxdb/_index.md +++ b/docs/sources/datasources/influxdb/_index.md @@ -52,6 +52,7 @@ The following documents will help you get started with the InfluxDB data source - [Configure the InfluxDB data source](./configure-influxdb-data-source/) - [InfluxDB query editor](./query-editor/) - [InfluxDB templates and variables](./template-variables/) +- [Troubleshoot issues with the InfluxDB data source](./troubleshooting/) Once you have configured the data source you can: diff --git a/docs/sources/datasources/influxdb/troubleshooting/index.md b/docs/sources/datasources/influxdb/troubleshooting/index.md new file mode 100644 index 00000000000..33fe67ecadf --- /dev/null +++ b/docs/sources/datasources/influxdb/troubleshooting/index.md @@ -0,0 +1,291 @@ +--- +aliases: + - ../../data-sources/influxdb/troubleshooting/ +description: Troubleshooting the InfluxDB data source in Grafana +keywords: + - grafana + - influxdb + - troubleshooting + - errors + - flux + - influxql + - sql +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Troubleshooting +title: Troubleshoot issues with the InfluxDB data source +weight: 600 +--- + +# Troubleshoot issues with the InfluxDB data source + +This document provides troubleshooting information for common errors you may encounter when using the InfluxDB data source in Grafana. + +## Connection errors + +The following errors occur when Grafana cannot establish or maintain a connection to InfluxDB. + +### Failed to connect to InfluxDB + +**Error message:** "error performing influxQL query" or "error performing flux query" or "error performing sql query" + +**Cause:** Grafana cannot establish a network connection to the InfluxDB server. + +**Solution:** + +1. Verify that the InfluxDB URL is correct in the data source configuration. +1. Check that InfluxDB is running and accessible from the Grafana server. +1. Ensure the URL includes the protocol (`http://` or `https://`). +1. Verify the port is correct (the InfluxDB default API port is `8086`). +1. Ensure there are no firewall rules blocking the connection. +1. For Grafana Cloud, ensure you have configured [Private data source connect](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) if your InfluxDB instance is not publicly accessible. + +### Request timed out + +**Error message:** "context deadline exceeded" or "request timeout" + +**Cause:** The connection to InfluxDB timed out before receiving a response. + +**Solution:** + +1. Check the network latency between Grafana and InfluxDB. +1. Verify that InfluxDB is not overloaded or experiencing performance issues. +1. Increase the timeout setting in the data source configuration under **Advanced HTTP Settings**. +1. Reduce the time range or complexity of your query. + +## Authentication errors + +The following errors occur when there are issues with authentication credentials or permissions. + +### Unauthorized (401) + +**Error message:** "401 Unauthorized" or "authorization failed" + +**Cause:** The authentication credentials are invalid or missing. + +**Solution:** + +1. Verify that the token or password is correct in the data source configuration. +1. For Flux and SQL, ensure the token has not expired. +1. For InfluxQL with InfluxDB 2.x, verify the token is set as an `Authorization` header with the value `Token `. +1. For InfluxDB 1.x, verify the username and password are correct. +1. Check that the token has the required permissions to access the specified bucket or database. + +### Forbidden (403) + +**Error message:** "403 Forbidden" or "access denied" + +**Cause:** The authenticated user or token does not have permission to access the requested resource. + +**Solution:** + +1. Verify the token has read access to the specified bucket or database. +1. Check the token's permissions in the InfluxDB UI under **API Tokens**. +1. Ensure the organization ID is correct for Flux queries. +1. For InfluxQL with InfluxDB 2.x, verify the DBRP mapping is configured correctly. + +## Configuration errors + +The following errors occur when the data source is not configured correctly. + +### Unknown influx version + +**Error message:** "unknown influx version" + +**Cause:** The query language is not properly configured in the data source settings. + +**Solution:** + +1. Open the data source configuration in Grafana. +1. Verify that a valid query language is selected: **Flux**, **InfluxQL**, or **SQL**. +1. Ensure the selected query language matches your InfluxDB version: + - Flux: InfluxDB 1.8+ and 2.x + - InfluxQL: InfluxDB 1.x and 2.x (with DBRP mapping) + - SQL: InfluxDB 3.x only + +### Invalid data source info received + +**Error message:** "invalid data source info received" + +**Cause:** The data source configuration is incomplete or corrupted. + +**Solution:** + +1. Delete and recreate the data source. +1. Ensure all required fields are populated based on your query language: + - **Flux:** URL, Organization, Token, Default Bucket + - **InfluxQL:** URL, Database, User, Password + - **SQL:** URL, Database, Token + +### DBRP mapping required + +**Error message:** "database not found" or queries return no data with InfluxQL on InfluxDB 2.x + +**Cause:** InfluxQL queries on InfluxDB 2.x require a Database and Retention Policy (DBRP) mapping. + +**Solution:** + +1. Create a DBRP mapping in InfluxDB using the CLI or API. +1. Refer to [Manage DBRP Mappings](https://docs.influxdata.com/influxdb/cloud/query-data/influxql/dbrp/) for guidance. +1. Verify the database name in Grafana matches the DBRP mapping. + +## Query errors + +The following errors occur when there are issues with query syntax or execution. + +### Query syntax error + +**Error message:** "error parsing query: found THING" or "failed to parse query: found WERE, expected ; at line 1, char 38" + +**Cause:** The query contains invalid syntax. + +**Solution:** + +1. Check your query syntax for typos or invalid keywords. +1. For InfluxQL, verify the query follows the correct syntax: + + ```sql + SELECT FROM WHERE + ``` + +1. For Flux, ensure proper pipe-forward syntax and function calls. +1. Use the InfluxDB UI or CLI to test your query directly. + +### Query timeout limit exceeded + +**Error message:** "query-timeout limit exceeded" + +**Cause:** The query took longer than the configured timeout limit in InfluxDB. + +**Solution:** + +1. Reduce the time range of your query. +1. Add more specific filters to limit the data scanned. +1. Increase the query timeout setting in InfluxDB if you have admin access. +1. Optimize your query to reduce complexity. + +### Too many series or data points + +**Error message:** "max-series-per-database limit exceeded" or "A query returned too many data points and the results have been truncated" + +**Cause:** The query is returning more data than the configured limits allow. + +**Solution:** + +1. Reduce the time range of your query. +1. Add filters to limit the number of series returned. +1. Increase the **Max series** setting in the data source configuration under **Advanced Database Settings**. +1. Use aggregation functions to reduce the number of data points. +1. For Flux, use `aggregateWindow()` to downsample data. + +### No time column found + +**Error message:** "no time column found" + +**Cause:** The query result does not include a time column, which is required for time series visualization. + +**Solution:** + +1. Ensure your query includes a time field. +1. For Flux, verify the query includes `_time` in the output. +1. For SQL, ensure the query returns a timestamp column. +1. Check that the time field is not being filtered out or excluded. + +## Health check errors + +The following errors occur when testing the data source connection. + +### Error getting flux query buckets + +**Error message:** "error getting flux query buckets" + +**Cause:** The health check query `buckets()` failed to return results. + +**Solution:** + +1. Verify the token has permission to list buckets. +1. Check that the organization ID is correct. +1. Ensure InfluxDB is running and accessible. + +### Error connecting InfluxDB influxQL + +**Error message:** "error connecting InfluxDB influxQL" + +**Cause:** The health check query `SHOW MEASUREMENTS` failed. + +**Solution:** + +1. Verify the database name is correct. +1. Check that the user has permission to run `SHOW MEASUREMENTS`. +1. Ensure the database exists and contains measurements. +1. For InfluxDB 2.x, verify DBRP mapping is configured. + +### 0 measurements found + +**Error message:** "data source is working. 0 measurements found" + +**Cause:** The connection is successful, but the database contains no measurements. + +**Solution:** + +1. Verify you are connecting to the correct database. +1. Check that data has been written to the database. +1. If the database is new, add some test data to verify the connection. + +## Other common issues + +The following issues don't produce specific error messages but are commonly encountered. + +### Empty query results + +**Cause:** The query returns no data. + +**Solution:** + +1. Verify the time range includes data in your database. +1. Check that the measurement and field names are correct. +1. Test the query directly in the InfluxDB UI or CLI. +1. Ensure filters are not excluding all data. +1. For InfluxQL, verify the retention policy contains data for the selected time range. + +### Slow query performance + +**Cause:** Queries take a long time to execute. + +**Solution:** + +1. Reduce the time range of your query. +1. Add more specific filters to limit the data scanned. +1. Increase the **Min time interval** setting to reduce the number of data points. +1. Check InfluxDB server performance and resource utilization. +1. For Flux, use `aggregateWindow()` to downsample data before visualization. +1. Consider using continuous queries or tasks to pre-aggregate data. + +### Data appears delayed or missing recent points + +**Cause:** The visualization doesn't show the most recent data. + +**Solution:** + +1. Check the dashboard time range and refresh settings. +1. Verify the **Min time interval** is not set too high. +1. Ensure InfluxDB has finished writing the data. +1. Check for clock synchronization issues between Grafana and InfluxDB. + +## Get additional help + +If you continue to experience issues after following this troubleshooting guide: + +1. Check the [InfluxDB documentation](https://docs.influxdata.com/) for API-specific guidance. +1. Review the [Grafana community forums](https://community.grafana.com/) for similar issues. +1. Contact Grafana Support if you're an Enterprise, Cloud Pro or Cloud Contracted user. +1. When reporting issues, include: + - Grafana version + - InfluxDB version and product (OSS, Cloud, Enterprise) + - Query language (Flux, InfluxQL, or SQL) + - Error messages (redact sensitive information) + - Steps to reproduce + - Relevant configuration such as data source settings, HTTP method, and TLS settings (redact tokens, passwords, and other credentials) diff --git a/docs/sources/datasources/mssql/_index.md b/docs/sources/datasources/mssql/_index.md index a5e00da6dcb..b7ea159e972 100644 --- a/docs/sources/datasources/mssql/_index.md +++ b/docs/sources/datasources/mssql/_index.md @@ -99,12 +99,27 @@ refs: destination: /docs/grafana//administration/data-source-management/#query-and-resource-caching - pattern: /docs/grafana-cloud/ destination: /docs/grafana//administration/data-source-management/#query-and-resource-caching + mssql-troubleshoot: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/mssql/troubleshooting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/mssql/troubleshooting/ + postgres: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/postgres/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/postgres/ + mysql: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/mysql/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/mysql/ --- # Microsoft SQL Server (MSSQL) data source Grafana ships with built-in support for Microsoft SQL Server (MSSQL). -You can query and visualize data from any Microsoft SQL Server 2005 or newer, including the Microsoft Azure SQL Database. +You can query and visualize data from any Microsoft SQL Server 2005 or newer, including Microsoft Azure SQL Database. Use this data source to create dashboards, explore SQL data, and monitor MSSQL-based workloads in real time. @@ -113,10 +128,33 @@ The following documentation helps you get started working with the Microsoft SQL - [Configure the Microsoft SQL Server data source](ref:configure-mssql-data-source) - [Microsoft SQL Server query editor](ref:mssql-query-editor) - [Microsoft SQL Server template variables](ref:mssql-template-variables) +- [Troubleshoot Microsoft SQL Server data source issues](ref:mssql-troubleshoot) -## Get the most out of the data source +## Supported versions -After installing and configuring the Microsoft SQL Server data source, you can: +This data source supports the following Microsoft SQL Server versions: + +- Microsoft SQL Server 2005 and newer +- Microsoft Azure SQL Database +- Azure SQL Managed Instance + +Grafana recommends using the latest available service pack for your SQL Server version for optimal compatibility. + +## Key capabilities + +The Microsoft SQL Server data source supports: + +- **Time series queries:** Visualize metrics over time using the built-in time grouping macros. +- **Table queries:** Display query results in table format for any valid SQL query. +- **Template variables:** Create dynamic dashboards with variable-driven queries. +- **Annotations:** Overlay events from SQL Server on your dashboard graphs. +- **Alerting:** Create alerts based on SQL Server query results. +- **Stored procedures:** Execute stored procedures and visualize results. +- **Macros:** Simplify queries with built-in macros for time filtering and grouping. + +## Additional resources + +After configuring the Microsoft SQL Server data source, you can: - Create a wide variety of [visualizations](ref:visualizations) - Configure and use [templates and variables](ref:variables) @@ -124,3 +162,8 @@ After installing and configuring the Microsoft SQL Server data source, you can: - Add [annotations](ref:annotate-visualizations) - Set up [alerting](ref:alerting) - Optimize performance with [query caching](ref:query-caching) + +## Related data sources + +- [PostgreSQL](ref:postgres) - For PostgreSQL databases. +- [MySQL](ref:mysql) - For MySQL and MariaDB databases. diff --git a/docs/sources/datasources/mssql/configure/index.md b/docs/sources/datasources/mssql/configure/index.md index 7ce6398f1cc..f41deeb51dd 100644 --- a/docs/sources/datasources/mssql/configure/index.md +++ b/docs/sources/datasources/mssql/configure/index.md @@ -89,6 +89,26 @@ refs: destination: /docs/grafana//setup-grafana/configure-access/configure-authentication/azuread/#enable-azure-ad-oauth-in-grafana - pattern: /docs/grafana-cloud/ destination: /docs/grafana//setup-grafana/configure-access/configure-authentication/azuread/#enable-azure-ad-oauth-in-grafana + mssql-query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/mssql/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/mssql/query-editor/ + mssql-template-variables: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/mssql/template-variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/mssql/template-variables/ + alerting: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/ + mssql-troubleshoot: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/mssql/troubleshooting/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/mssql/troubleshooting/ --- # Configure the Microsoft SQL Server data source @@ -97,13 +117,28 @@ This document provides instructions for configuring the Microsoft SQL Server dat ## Before you begin -- Grafana comes with a built-in MSSQL data source plugin, eliminating the need to install a plugin. +Before configuring the Microsoft SQL Server data source, ensure you have the following: -- You must have the `Organization administrator` role to configure the MSSQL data source. Organization administrators can also [configure the data source via YAML](#provision-the-data-source) with the Grafana provisioning system. +- **Grafana permissions:** You must have the `Organization administrator` role to configure data sources. Organization administrators can also [configure the data source via YAML](#provision-the-data-source) with the Grafana provisioning system. -- Familiarize yourself with your MSSQL security configuration and gather any necessary security certificates and client keys. +- **A running SQL Server instance:** Microsoft SQL Server 2005 or newer, Azure SQL Database, or Azure SQL Managed Instance. -- Verify that data from MSSQL is being written to your Grafana instance. +- **Network access:** Grafana must be able to reach your SQL Server. The default port is `1433`. + +- **Authentication credentials:** Depending on your authentication method, you need one of: + - SQL Server login credentials (username and password). + - Windows/Kerberos credentials and configuration (not supported in Grafana Cloud). + - Azure Entra ID app registration or managed identity. + +- **Security certificates:** If using encrypted connections, gather any necessary TLS/SSL certificates. + +{{< admonition type="note" >}} +Grafana ships with a built-in Microsoft SQL Server data source plugin. No additional installation is required. +{{< /admonition >}} + +{{< admonition type="tip" >}} +**Grafana Cloud users:** If your SQL Server is in a private network, you can configure [Private data source connect](ref:private-data-source-connect) to establish connectivity. +{{< /admonition >}} ## Add the MSSQL data source @@ -382,3 +417,48 @@ datasources: secureJsonData: password: 'Password!' ``` + +### Configure with Terraform + +You can configure the Microsoft SQL Server data source using [Terraform](https://www.terraform.io/) with the [Grafana Terraform provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs). + +For more information about provisioning resources with Terraform, refer to the [Grafana as code using Terraform](https://grafana.com/docs/grafana-cloud/developer-resources/infrastructure-as-code/terraform/) documentation. + +#### Terraform example + +The following example creates a basic Microsoft SQL Server data source: + +```hcl +resource "grafana_data_source" "mssql" { + name = "MSSQL" + type = "mssql" + url = "localhost:1433" + user = "grafana" + + json_data_encoded = jsonencode({ + database = "grafana" + maxOpenConns = 100 + maxIdleConns = 100 + maxIdleConnsAuto = true + connMaxLifetime = 14400 + connectionTimeout = 0 + encrypt = "false" + }) + + secure_json_data_encoded = jsonencode({ + password = "Password!" + }) +} +``` + +For all available configuration options, refer to the [Grafana provider data source resource documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source). + +## Next steps + +After configuring your Microsoft SQL Server data source, you can: + +- [Write queries](ref:mssql-query-editor) using the query editor to explore and visualize your data +- [Create template variables](ref:mssql-template-variables) to build dynamic, reusable dashboards +- [Add annotations](ref:annotate-visualizations) to overlay SQL Server events on your graphs +- [Set up alerting](ref:alerting) to create alert rules based on your SQL Server data +- [Troubleshoot issues](ref:mssql-troubleshoot) if you encounter problems with your data source diff --git a/docs/sources/datasources/mssql/troubleshooting/index.md b/docs/sources/datasources/mssql/troubleshooting/index.md new file mode 100644 index 00000000000..a62f3eb59e1 --- /dev/null +++ b/docs/sources/datasources/mssql/troubleshooting/index.md @@ -0,0 +1,333 @@ +--- +description: Troubleshoot common problems with the Microsoft SQL Server data source in Grafana +keywords: + - grafana + - MSSQL + - Microsoft + - SQL + - troubleshooting + - errors +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Troubleshooting +title: Troubleshoot Microsoft SQL Server data source issues +weight: 400 +refs: + configure-mssql-data-source: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/mssql/configure/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/mssql/configure/ + mssql-query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//datasources/mssql/query-editor/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//datasources/mssql/query-editor/ + private-data-source-connect: + - pattern: /docs/grafana/ + destination: /docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/ +--- + +# Troubleshoot Microsoft SQL Server data source issues + +This document provides solutions to common issues you may encounter when configuring or using the Microsoft SQL Server (MSSQL) data source in Grafana. + +## Connection errors + +These errors occur when Grafana cannot establish or maintain a connection to the Microsoft SQL Server. + +### Unable to connect to the server + +**Error message:** "Unable to open tcp connection" or "dial tcp: connection refused" + +**Cause:** Grafana cannot establish a network connection to the SQL Server. + +**Solution:** + +1. Verify that the SQL Server is running and accessible. +1. Check that the host and port are correct in the data source configuration. The default SQL Server port is `1433`. +1. Ensure there are no firewall rules blocking the connection between Grafana and SQL Server. +1. Verify that SQL Server is configured to allow remote connections. +1. For Grafana Cloud, ensure you have configured [Private data source connect](ref:private-data-source-connect) if your SQL Server instance is not publicly accessible. + +### Connection timeout + +**Error message:** "Connection timed out" or "I/O timeout" + +**Cause:** The connection to SQL Server timed out before receiving a response. + +**Solution:** + +1. Check the network latency between Grafana and SQL Server. +1. Verify that SQL Server is not overloaded or experiencing performance issues. +1. Increase the **Connection timeout** setting in the data source configuration under **Additional settings**. +1. Check if any network devices (load balancers, proxies) are timing out the connection. + +### Encryption-related connection failures + +**Error message:** "TLS handshake failed" or "certificate verify failed" + +**Cause:** There is a mismatch between the encryption settings in Grafana and what the SQL Server supports or requires. + +**Solution:** + +1. For older versions of SQL Server (2008, 2008R2), set the **Encrypt** option to **Disable** or **False** in the data source configuration. +1. Verify that the SQL Server has a valid SSL certificate if encryption is enabled. +1. Check that the certificate is trusted by the Grafana server. +1. Ensure you're using the latest available service pack for your SQL Server version for optimal compatibility. + +### Named instance connection issues + +**Error message:** "Cannot connect to named instance" or connection fails when using instance name + +**Cause:** Grafana cannot resolve the SQL Server named instance. + +**Solution:** + +1. Use the format `hostname\instancename` or `hostname\instancename,port` in the **Host** field. +1. Verify that the SQL Server Browser service is running on the SQL Server machine. +1. If the Browser service is unavailable, specify the port number directly: `hostname,port`. +1. Check that UDP port 1434 is open if using the SQL Server Browser service. + +## Authentication errors + +These errors occur when there are issues with authentication credentials or permissions. + +### Login failed for user + +**Error message:** "Login failed for user 'username'" or "Authentication failed" + +**Cause:** The authentication credentials are invalid or the user doesn't have permission to access the database. + +**Solution:** + +1. Verify that the username and password are correct. +1. Check that the user exists in SQL Server and is enabled. +1. Ensure the user has access to the specified database. +1. For Windows Authentication, verify that the credentials are in the correct format (`DOMAIN\User`). +1. Check that the SQL Server authentication mode allows the type of login you're using (SQL Server Authentication, Windows Authentication, or Mixed Mode). + +### Access denied to database + +**Error message:** "Cannot open database 'dbname' requested by the login" + +**Cause:** The authenticated user doesn't have permission to access the specified database. + +**Solution:** + +1. Verify that the database name is correct in the data source configuration. +1. Ensure the user is mapped to the database with appropriate permissions. +1. Grant at least `SELECT` permission on the required tables: + + ```sql + USE [your_database] + GRANT SELECT ON dbo.YourTable TO [your_user] + ``` + +1. Check that the user doesn't have any conflicting permissions from the public role. + +### Windows Authentication (Kerberos) issues + +**Error message:** "Kerberos authentication failed" or "Cannot initialize Kerberos" + +**Cause:** Kerberos configuration is incorrect or incomplete. + +**Solution:** + +1. Verify that the Kerberos configuration file (`krb5.conf`) path is correct in the data source settings. +1. For keytab authentication, ensure the keytab file exists and is readable by Grafana. +1. Check that the realm and KDC settings are correct in the Kerberos configuration. +1. Verify DNS is correctly resolving the KDC servers. +1. Ensure the service principal name (SPN) is registered for the SQL Server instance. + +{{< admonition type="note" >}} +Kerberos authentication is not supported in Grafana Cloud. +{{< /admonition >}} + +### Azure Entra ID authentication errors + +**Error message:** "AADSTS error codes" or "Azure AD authentication failed" + +**Cause:** Azure Entra ID (formerly Azure AD) authentication is misconfigured. + +**Solution:** + +1. For **App Registration** authentication: + - Verify the tenant ID, client ID, and client secret are correct. + - Ensure the app registration has been added as a user in the Azure SQL database. + - Check that the client secret hasn't expired. + +1. For **Managed Identity** authentication: + - Verify `managed_identity_enabled = true` is set in the Grafana server configuration. + - Ensure the managed identity has been added to the Azure SQL database. + - Confirm the Azure resource hosting Grafana has managed identity enabled. + +1. For **Current User** authentication: + - Ensure `user_identity_enabled = true` is set in the Grafana server configuration. + - Verify the app registration is configured to issue both Access Tokens and ID Tokens. + - Check that the required API permissions are configured (`user_impersonation` for Azure SQL). + +For detailed Azure authentication configuration, refer to [Configure the Microsoft SQL Server data source](ref:configure-mssql-data-source). + +## Query errors + +These errors occur when there are issues with query syntax or configuration. + +### Time column not found or invalid + +**Error message:** "Could not find time column" or time series visualization shows no data + +**Cause:** The query doesn't return a properly formatted `time` column for time series visualization. + +**Solution:** + +1. Ensure your query includes a column named `time` when using the **Time series** format. +1. Use the `$__time()` macro to rename your date column: `$__time(your_date_column)`. +1. Verify the time column is of a valid SQL date/time type (`datetime`, `datetime2`, `date`) or contains Unix epoch values. +1. Ensure the result set is sorted by the time column using `ORDER BY`. + +### Macro expansion errors + +**Error message:** "Error parsing query" or macros appear unexpanded in the query + +**Cause:** Grafana macros are being used incorrectly. + +**Solution:** + +1. Verify macro syntax: use `$__timeFilter(column)` not `$_timeFilter(column)`. +1. Macros don't work inside stored procedures—use explicit date parameters instead. +1. Check that the column name passed to macros exists in your table. +1. View the expanded query by clicking **Generated SQL** after running the query to debug macro expansion. + +### Timezone and time shift issues + +**Cause:** Time series data appears shifted or doesn't align with expected times. + +**Solution:** + +1. Store timestamps in UTC in your database to avoid timezone issues. +1. Time macros (`$__time`, `$__timeFilter`, etc.) always expand to UTC values. +1. If your timestamps are stored in local time, convert them to UTC in your query: + + ```sql + SELECT + your_datetime_column AT TIME ZONE 'Your Local Timezone' AT TIME ZONE 'UTC' AS time, + value + FROM your_table + ``` + +1. Don't pass timezone parameters to time macros—they're not supported. + +### Query returns too many rows + +**Error message:** "Result set too large" or browser becomes unresponsive + +**Cause:** The query returns more data than can be efficiently processed. + +**Solution:** + +1. Add time filters using `$__timeFilter(column)` to limit data to the dashboard time range. +1. Use aggregations (`AVG`, `SUM`, `COUNT`) with `GROUP BY` instead of returning raw rows. +1. Add a `TOP` clause to limit results: `SELECT TOP 1000 ...`. +1. Use the `$__timeGroup()` macro to aggregate data into time intervals. + +### Stored procedure returns no data + +**Cause:** Stored procedure output isn't being captured correctly. + +**Solution:** + +1. Ensure the stored procedure uses `SELECT` statements, not just variable assignments. +1. Remove `SET NOCOUNT ON` if present, or ensure it's followed by a `SELECT` statement. +1. Verify the stored procedure parameters are being passed correctly. +1. Test the stored procedure directly in SQL Server Management Studio with the same parameters. + +For more information on using stored procedures, refer to the [query editor documentation](ref:mssql-query-editor). + +## Performance issues + +These issues relate to slow queries or high resource usage. + +### Slow query execution + +**Cause:** Queries take a long time to execute. + +**Solution:** + +1. Reduce the dashboard time range to limit data volume. +1. Add indexes to columns used in `WHERE` clauses and time filters. +1. Use aggregations instead of returning individual rows. +1. Increase the **Min time interval** setting to reduce the number of data points. +1. Review the query execution plan in SQL Server Management Studio to identify bottlenecks. + +### Connection pool exhaustion + +**Error message:** "Too many connections" or "Connection pool exhausted" + +**Cause:** Too many concurrent connections to the database. + +**Solution:** + +1. Increase the **Max open** connection limit in the data source configuration. +1. Enable **Auto max idle** to automatically manage idle connections. +1. Reduce the number of panels querying the same data source simultaneously. +1. Check for long-running queries that might be holding connections. + +## Other common issues + +The following issues don't produce specific error messages but are commonly encountered. + +### System databases appear in queries + +**Cause:** Queries accidentally access system databases. + +**Solution:** + +1. The query editor automatically excludes `tempdb`, `model`, `msdb`, and `master` from the database dropdown. +1. Always specify the database in your data source configuration to restrict access. +1. Ensure the database user only has permissions on the intended database. + +### Template variable queries fail + +**Cause:** Variable queries return unexpected results or errors. + +**Solution:** + +1. Verify the variable query syntax is valid SQL that returns a single column. +1. Check that the data source connection is working. +1. Ensure the user has permission to access the tables referenced in the variable query. +1. Test the query in the query editor before using it as a variable query. + +### Data appears incorrect or misaligned + +**Cause:** Data formatting or type conversion issues. + +**Solution:** + +1. Use explicit column aliases to ensure consistent naming: `SELECT value AS metric`. +1. Verify numeric columns are actually numeric types, not strings. +1. Check for `NULL` values that might affect aggregations. +1. Use the `FILL` option in `$__timeGroup()` macro to handle missing data points. + +## Get additional help + +If you continue to experience issues after following this troubleshooting guide: + +1. Check the [Grafana community forums](https://community.grafana.com/) for similar issues. +1. Review the [Grafana GitHub issues](https://github.com/grafana/grafana/issues) for known bugs. +1. Enable debug logging in Grafana to capture detailed error information. +1. Check SQL Server logs for additional error details. +1. Contact Grafana Support if you're an Enterprise or Cloud customer. + +When reporting issues, include: + +- Grafana version +- SQL Server version +- Error messages (redact sensitive information) +- Steps to reproduce +- Relevant query examples (redact sensitive data) diff --git a/docs/sources/datasources/mysql/troubleshoot/index.md b/docs/sources/datasources/mysql/troubleshoot/index.md new file mode 100644 index 00000000000..0fcf80e55ac --- /dev/null +++ b/docs/sources/datasources/mysql/troubleshoot/index.md @@ -0,0 +1,80 @@ +--- +description: Learn how to troubleshoot common problems with the Grafana MySQL data source plugin +keywords: + - grafana + - mysql + - query +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Troubleshoot +title: Troubleshoot common problems with the Grafana MySQL data source plugin +weight: 40 +refs: + variables: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/dashboards/variables/ + variable-syntax-advanced-variable-format-options: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/variable-syntax/#advanced-variable-format-options + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/dashboards/variables/variable-syntax/#advanced-variable-format-options + annotate-visualizations: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/build-dashboards/annotate-visualizations/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/dashboards/build-dashboards/annotate-visualizations/ + explore: + - pattern: /docs/grafana/ + destination: /docs/grafana//explore/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//explore/ + query-transform-data: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/query-transform-data/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/ + panel-inspector: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/panel-inspector/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/panel-inspector/ + query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/query-transform-data/#query-editors + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/#query-editors + alert-rules: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/alert-rules/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/ + template-annotations-and-labels: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/alerting-rules/templates/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/templates/ + configure-standard-options: + - pattern: /docs/grafana/ + - destination: /docs/grafana//panels-visualizations/configure-standard-options/ +--- + +# Troubleshoot common problems with the Grafana MySQL data source plugin + +This page lists common issues you might experience when setting up the Grafana MySQL data source plugin. + +### My data source connection fails when using the Grafana MySQL data source plugin + +- Check if the MySQL server is up and running. +- Make sure that your firewall is open for MySQL server (default port is `3306`). +- Ensure that you have the correct permissions to access the MySQL server and also have permission to access the database. +- If the error persists, create a new user for the Grafana MySQL data source plugin with correct permissions and try to connect with it. + +### What should I do if I see "An unexpected error happened" or "Could not connect to MySQL" after trying all of the above? + +- Check the Grafana logs for more details about the error. +- For Grafana Cloud customers, contact support. diff --git a/docs/sources/developer-resources/api-reference/http-api/dashboard.md b/docs/sources/developer-resources/api-reference/http-api/dashboard.md index abef6a8f5e6..1b5d32bb9f4 100644 --- a/docs/sources/developer-resources/api-reference/http-api/dashboard.md +++ b/docs/sources/developer-resources/api-reference/http-api/dashboard.md @@ -231,6 +231,10 @@ JSON Body schema: - **metadata.annotations.grafana.app/folder** - Optional field, the unique identifier of the folder under which the dashboard should be created. - **spec** – The dashboard json. +{{< admonition type="note" >}} +Custom labels and annotations in the metadata field are supported on some instances, with full support planned for all instances when these APIs reach general availability. If they are not yet supported on your instance, they will be ignored. +{{< /admonition >}} + **Example Response**: ```http @@ -521,6 +525,10 @@ JSON Body schema: - **metadata.annotations.grafana.app/message** - Optional field, to set a commit message for the version history. - **spec** – The dashboard json. +{{< admonition type="note" >}} +Custom labels and annotations in the metadata field are supported on some instances, with full support planned for all instances when these APIs reach general availability. If they are not yet supported on your instance, they will be ignored. +{{< /admonition >}} + **Example Response**: ```http diff --git a/docs/sources/developer-resources/api-reference/http-api/folder.md b/docs/sources/developer-resources/api-reference/http-api/folder.md index f042a3a5a3e..6a6b18abeba 100644 --- a/docs/sources/developer-resources/api-reference/http-api/folder.md +++ b/docs/sources/developer-resources/api-reference/http-api/folder.md @@ -259,6 +259,10 @@ JSON Body schema: - **metadata.annotations.grafana.app/folder** - Optional field, the unique identifier of the parent folder under which the folder should be created. Requires nested folders to be enabled. - **spec.title** – The title of the folder. +{{< admonition type="note" >}} +Custom labels and annotations in the metadata field are supported on some instances, with full support planned for all instances when these APIs reach general availability. If they are not yet supported on your instance, they will be ignored. +{{< /admonition >}} + **Example Response**: ```http @@ -337,6 +341,10 @@ JSON Body schema: - **metadata.annotations.grafana.app/folder** - Optional field, the unique identifier of the parent folder under which the folder should be - update this to move the folder under a different parent folder. Requires nested folders to be enabled. - **spec.title** – The title of the folder. +{{< admonition type="note" >}} +Custom labels and annotations in the metadata field are supported on some instances, with full support planned for all instances when these APIs reach general availability. If they are not yet supported on your instance, they will be ignored. +{{< /admonition >}} + **Example Response**: ```http diff --git a/docs/sources/developer-resources/api-reference/http-api/library_element.md b/docs/sources/developer-resources/api-reference/http-api/library_element.md index ea241c220e1..ce367c485ef 100644 --- a/docs/sources/developer-resources/api-reference/http-api/library_element.md +++ b/docs/sources/developer-resources/api-reference/http-api/library_element.md @@ -41,7 +41,8 @@ Query parameters: - `sortDirection`: Sort order of elements. Use `alpha-asc` for ascending and `alpha-desc` for descending sort order. - `typeFilter`: A comma separated list of types to filter the elements by. - `excludeUid`: Element UID to exclude from search results. -- `folderFilter`: A comma separated list of folder IDs to filter the elements by. +- `folderFilter`: **Deprecated.** A comma separated list of folder IDs to filter the elements by. Use `folderFilterUIDs` instead. +- `folderFilterUIDs`: A comma separated list of folder UIDs to filter the elements by. - `perPage`: The number of results per page; default is 100. - `page`: The page for a set of records, given that only `perPage` records are returned at a time. Numbering starts at `1`. diff --git a/docs/sources/developer-resources/api-reference/http-api/preferences.md b/docs/sources/developer-resources/api-reference/http-api/preferences.md index 1cd350ee059..079fa1ebce9 100644 --- a/docs/sources/developer-resources/api-reference/http-api/preferences.md +++ b/docs/sources/developer-resources/api-reference/http-api/preferences.md @@ -25,7 +25,7 @@ Keys: - **theme** - One of: `light`, `dark`, or an empty string for the default theme - **homeDashboardId** - Deprecated. Use `homeDashboardUID` instead. - **homeDashboardUID**: The `:uid` of a dashboard -- **timezone** - One of: `utc`, `browser`, or an empty string for the default +- **timezone** - Any valid IANA timezone string (e.g., `America/New_York`, `Europe/London`), `utc`, `browser`, or an empty string for the default. Omitting a key will cause the current value to be replaced with the system default value. diff --git a/docs/sources/developers/plugins/plugin.schema.json b/docs/sources/developers/plugins/plugin.schema.json index 1898cd46b94..cae948ce4f3 100644 --- a/docs/sources/developers/plugins/plugin.schema.json +++ b/docs/sources/developers/plugins/plugin.schema.json @@ -369,7 +369,7 @@ "description": "For data source plugins. Proxy routes used for plugin authentication and adding headers to HTTP requests made by the plugin. For more information, refer to [Authentication for data source plugins](https://grafana.com/developers/plugin-tools/how-to-guides/data-source-plugins/add-authentication-for-data-source-plugins).", "items": { "type": "object", - "description": "", + "description": "For data source plugins. Proxy routes used for plugin authentication and adding headers to HTTP requests made by the plugin. For more information, refer to [Authentication for data source plugins](https://grafana.com/developers/plugin-tools/how-to-guides/data-source-plugins/add-authentication-for-data-source-plugins).", "additionalProperties": false, "properties": { "path": { diff --git a/docs/sources/fundamentals/glossary/index.md b/docs/sources/fundamentals/glossary/index.md index eee83a7f2de..428764b4ae5 100644 --- a/docs/sources/fundamentals/glossary/index.md +++ b/docs/sources/fundamentals/glossary/index.md @@ -83,6 +83,11 @@ This topic lists words and abbreviations that are commonly used in the Grafana d A commonly-used visualization that displays data as points, lines, or bars. + + grafanactl + + A command-line tool that enables users to authenticate, manage multiple environments, and perform administrative tasks through Grafana's REST API. + mixin diff --git a/docs/sources/setup-grafana/configure-access/configure-authentication/anonymous-auth/index.md b/docs/sources/setup-grafana/configure-access/configure-authentication/anonymous-auth/index.md index 77df611f904..27c65e7bd02 100644 --- a/docs/sources/setup-grafana/configure-access/configure-authentication/anonymous-auth/index.md +++ b/docs/sources/setup-grafana/configure-access/configure-authentication/anonymous-auth/index.md @@ -38,13 +38,6 @@ Users can now view anonymous usage statistics, including the count of devices an The number of anonymous devices is not limited by default. The configuration option `device_limit` allows you to enforce a limit on the number of anonymous devices. This enables you to have greater control over the usage within your Grafana instance and keep the usage within the limits of your environment. Once the limit is reached, any new devices that try to access Grafana will be denied access. -To display anonymous users and devices for versions 10.2, 10.3, 10.4, you need to enable the feature toggle `displayAnonymousStats` - -```bash -[feature_toggles] -enable = displayAnonymousStats -``` - ## Configuration Example: @@ -67,3 +60,15 @@ device_limit = ``` If you change your organization name in the Grafana UI this setting needs to be updated to match the new name. + +## Licensing for anonymous access + +Grafana Enterprise (self-managed) licenses anonymous access as active users. + +Anonymous access lets people use Grafana without login credentials. It was an early way to share dashboards, but Public dashboards gives you a more secure way to share dashboards. + +### How anonymous usage is counted + +Grafana estimates anonymous active users from anonymous devices: + +- **Counting rule**: Grafana counts 1 anonymous user for every 3 anonymous devices detected. diff --git a/docs/sources/setup-grafana/configure-access/configure-scim-provisioning/_index.md b/docs/sources/setup-grafana/configure-access/configure-scim-provisioning/_index.md index 9ef98bbc433..a07dde69e08 100644 --- a/docs/sources/setup-grafana/configure-access/configure-scim-provisioning/_index.md +++ b/docs/sources/setup-grafana/configure-access/configure-scim-provisioning/_index.md @@ -54,18 +54,6 @@ SCIM offers several advantages for managing users and teams in Grafana: ## Authentication and access requirements -{{< admonition type="warning" title="Critical: Aligning SAML Identifier with SCIM externalId" >}} -When using SAML for authentication alongside SCIM provisioning, a critical security measure is to ensure proper alignment between the the SCIM user's `externalId` and the SAML user identifier. The unique identifier used for SCIM provisioning (which becomes the `externalId` in Grafana, often sourced from a stable IdP attribute like Entra ID's `user.objectid`) **must also be sent as a claim in the SAML assertion from your Identity Provider.** -Furthermore, the Grafana SAML configuration must be correctly set up to identify and use this specific claim for linking the authenticated SAML user to their SCIM-provisioned user. This can be achieved by either ensuring the primary SAML login identifier by using the `assertion_attribute_external_uid` setting in Grafana to explicitly set the name of the SAML claim that contains the stable unique identifier attribute. - -**Why is this important?** -A mismatch or inconsistent mapping between this SAML login identifier and the SCIM `externalId` creates a critical security vulnerability. If these two identifiers are not reliably and uniquely aligned for each individual user, Grafana may fail to correctly link an authenticated SAML session to the intended SCIM-provisioned user profile and its associated permissions. This can enable a malicious actor to impersonate another user—for instance, by crafting a SAML assertion that, due to the identifier misalignment, incorrectly grants them the access rights of the targeted user. - -Grafana relies on this linkage to correctly associate the authenticated user from SAML with the provisioned user from SCIM. Failure to ensure a consistent and unique identifier across both systems can break this linkage, leading to incorrect user mapping and potential unauthorized access. - -Always verify that your SAML identity provider is configured to send a stable, unique user identifier that your SCIM configuration maps to `externalId`. Refer to your identity provider's documentation and the specific Grafana SCIM integration guides (e.g., for [Entra ID](configure-scim-with-azuread/) or [Okta](configure-scim-with-okta/)) for detailed instructions on configuring these attributes correctly. -{{< /admonition >}} - When you enable SCIM in Grafana, the following requirements and restrictions apply: 1. **Use the same identity provider for user provisioning and for authentication flow**: You must use the same identity provider for both authentication and user provisioning. @@ -74,6 +62,12 @@ When you enable SCIM in Grafana, the following requirements and restrictions app - Configure `userUID` SAML assertion in [Entra ID](/docs/grafana//setup-grafana/configure-access/configure-authentication/saml/configure-saml-with-azuread/#configure-saml-assertions-when-using-scim-provisioning) - Configure `userUID` SAML assertion in [Okta](/docs/grafana//setup-grafana/configure-access/configure-authentication/saml/configure-saml-with-okta/#configure-saml-assertions-when-using-scim-provisioning) +### Align SAML identifier with SCIM `externalId` + +When you use SAML with SCIM provisioning, align the SCIM `externalId` with the SAML user identifier. Use a stable IdP attribute (for example, Entra ID `user.objectid`) as the SCIM `externalId`, and send that same value as a SAML claim. Configure Grafana to read this claim with the `assertion_attribute_external_uid` setting so SAML authentication links to the SCIM-provisioned user and its permissions. + +If the SAML identifier and SCIM `externalId` differ, Grafana may not link the authenticated user to the intended SCIM profile, which can result in incorrect access. Verify your IdP sends a stable, unique identifier and that it matches the SCIM `externalId`. Refer to your IdP docs and the Grafana SCIM integration guides for [Entra ID](configure-scim-with-azuread/) and [Okta](configure-scim-with-okta/) for attribute configuration details. + ## Configure SCIM using the Grafana user interface You can configure SCIM in Grafana using the Grafana user interface. To do this, navigate to **Administration > Authentication > SCIM**. diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 13c2b77fd2f..d9125991c12 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -642,6 +642,12 @@ You must also provide the `rudderstack_write_key` to enable this feature. Optional. If tracking with RudderStack is enabled, you can provide a custom URL to load the RudderStack SDK. +#### `rudderstack_v3_sdk_url` + +Optional. +This is mirroring the old configuration option, which will be deprecated. +If `rudderstack_sdk_url` and `rudderstack_v3_sdk_url` are both set, the feature toggle `rudderstackUpgrade` will control which one is loaded. + #### `rudderstack_config_url` Optional. @@ -1776,6 +1782,13 @@ Specify the frequency of polling for Alertmanager configuration changes. The def The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), for example, 30s or 1m. +#### `alertmanager_max_template_output_bytes` + +Maximum size in bytes that the expanded result of any single template expression (e.g. {{ .CommonAnnotations.description }}, {{ .ExternalURL }}, etc.) may reach during notification rendering. +The limit is checked after template execution for each templated field, but before the value is inserted into the final notification payload sent to the receiver. +If exceeded, the notification will contain output truncated up to the limit and a warning will be logged. +The default value is 10,485,760 bytes (10Mb). + #### `ha_redis_address` Redis server address or addresses. It can be a single Redis address if using Redis standalone, @@ -2039,6 +2052,10 @@ This section applies only to rules imported as Grafana-managed rules. For more i Set the query offset to imported Grafana-managed rules when `query_offset` is not defined in the original rule group configuration. The default value is `1m`. +#### `default_datasource_uid` + +Set the default data source UID to use for query execution when importing Prometheus rules. Grafana uses this default when the `X-Grafana-Alerting-Datasource-UID` header isn't provided during import. If this option isn't set, the header becomes required. The default value is empty. +
### `[annotations]` @@ -2142,17 +2159,13 @@ Configures settings around the short link feature. #### `expire_time` -Short links that are never accessed are considered expired or stale and are deleted as cleanup. +Short links that are never accessed are considered expired or stale and can be deleted as cleanup. Set the expiration time in days. -The default is `7` days. +The default is `-1` days (never expire). The maximum is `365` days. -A setting above the maximum uses the value `365` instead. -Setting `0` means the short links are cleaned up approximately every 10 minutes. -A negative value such as `-1` disables expiry. -{{< admonition type="caution" >}} -Short links without an expiration increase the size of the database and can't be deleted. Grafana recommends setting a duration based on your specific use case -{{< /admonition >}} +A setting above the maximum uses the value `365` instead. +A negative value such as `-1` disables expiry.
@@ -2823,9 +2836,11 @@ For more information about Grafana Enterprise, refer to [Grafana Enterprise](../ Keys of features to enable, separated by space. -#### `FEATURE_TOGGLE_NAME = false` +#### `FEATURE_NAME = ` -Some feature toggles for stable features are on by default. Use this setting to disable an on-by-default feature toggle with the name FEATURE_TOGGLE_NAME, for example, `exploreMixedDatasource = false`. +Use a key-value pair to set feature flag values explicitly, overriding any default values. A few different types are supported, following the OpenFeature specification. See the defaults.ini file for more details. + +For example, to disable an on-by-default feature toggle named `exploreMixedDatasource`, specify `exploreMixedDatasource = false`.
diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index b80fa49f815..b7f55555e07 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -31,7 +31,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes | | `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes | | `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes | -| `unifiedRequestLog` | Writes error logs to the request logger | Yes | | `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes | | `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers | Yes | | `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled | Yes | @@ -67,7 +66,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `sharingDashboardImage` | Enables image sharing functionality for dashboards | Yes | | `tabularNumbers` | Use fixed-width numbers globally in the UI | | | `azureResourcePickerUpdates` | Enables the updated Azure Monitor resource picker | Yes | -| `tempoSearchBackendMigration` | Run search queries through the tempo backend | | | `opentsdbBackendMigration` | Run queries through the data source backend | | ## Public preview feature toggles diff --git a/docs/sources/setup-grafana/installation/debian/index.md b/docs/sources/setup-grafana/installation/debian/index.md index 067bcb29f6a..900c4a4b9d1 100644 --- a/docs/sources/setup-grafana/installation/debian/index.md +++ b/docs/sources/setup-grafana/installation/debian/index.md @@ -46,7 +46,7 @@ Complete the following steps to install Grafana from the APT repository: 1. Install the prerequisite packages: ```bash - sudo apt-get install -y apt-transport-https software-properties-common wget + sudo apt-get install -y apt-transport-https wget ``` 1. Import the GPG key: diff --git a/docs/sources/shared/datasources/tempo-editor-traceql.md b/docs/sources/shared/datasources/tempo-editor-traceql.md index 54496c339e3..003a449fd96 100644 --- a/docs/sources/shared/datasources/tempo-editor-traceql.md +++ b/docs/sources/shared/datasources/tempo-editor-traceql.md @@ -135,9 +135,12 @@ You can use the **Span Limit** field in **Options** section of the TraceQL query This field sets the maximum number of spans to return for each span set. By default, the maximum value that you can set for the **Span Limit** value (or the spss query) is 100. In Tempo configuration, this value is controlled by the `max_spans_per_span_set` parameter and can be modified by your Tempo administrator. -Grafana Cloud users can contact Grafana Support to request a change. Entering a value higher than the default results in an error. +{{< admonition type="note" >}} +Changing the value of `max_spans_per_span_set` isn't supported in Grafana Cloud. +{{< /admonition >}} + ### Focus on traces or spans Under **Options**, you can choose to display the table as **Traces** or **Spans** focused. diff --git a/docs/sources/tutorials/alerting-get-started-pt6/index.md b/docs/sources/tutorials/alerting-get-started-pt6/index.md index 470330237e2..edf5e61e178 100644 --- a/docs/sources/tutorials/alerting-get-started-pt6/index.md +++ b/docs/sources/tutorials/alerting-get-started-pt6/index.md @@ -23,6 +23,8 @@ killercoda: This tutorial is a continuation of the [Get started with Grafana Alerting - Route alerts using dynamic labels](http://www.grafana.com/tutorials/alerting-get-started-pt5/) tutorial. +{{< youtube id="mqj_hN24zLU" >}} + In this tutorial you will learn how to: diff --git a/docs/sources/upgrade-guide/upgrade-v12.0/index.md b/docs/sources/upgrade-guide/upgrade-v12.0/index.md index 779950c0fd4..b166cc2c022 100644 --- a/docs/sources/upgrade-guide/upgrade-v12.0/index.md +++ b/docs/sources/upgrade-guide/upgrade-v12.0/index.md @@ -80,3 +80,87 @@ Since Grafana 10.2, the endpoint to check compatible versions when installing a #### What if I want to ignore the compatibility check? We _do not_ recommend installing plugins declared as incompatible. However, if you need to force install a plugin despite it being declared as incompatible, refer to the [Installing a plugin from a ZIP](https://grafana.com/docs/grafana/latest/administration/plugin-management/#install-a-plugin-from-a-zip-file) guidance. + +### Annotation table migration + +**Plan for increased disk usage when upgrading from Grafana v11.x** + +Upgrading from Grafana v11.x to Grafana v12.x triggers a full-table rewrite of the `annotation` table. The migration populates the new `dashboard_uid` column, which causes the database to rewrite the entire table and rebuild its indexes. + +Environments with large annotation datasets can experience significant temporary disk usage increase, which may lead to: + +- Rapid disk consumption on the database data volume +- Database migration failures (for example, "could not extend file: No space left on device") +- Grafana startup failures +- Extended downtime during the upgrade process + +#### How do I know if I'm affected? + +You're affected if you're upgrading from Grafana v11.x to v12.x and you have a large `annotation` table in your database. + +To check your annotation table size, connect to your database and check the table size. + +For PostgreSQL, run the following query: + +```sql +SELECT + pg_size_pretty(pg_relation_size('annotation')) AS table_size, + pg_size_pretty(pg_indexes_size('annotation')) AS indexes_size, + pg_size_pretty(pg_total_relation_size('annotation')) AS total_size; +``` + +For MySQL, run the following query: + +```sql +SELECT + ROUND(data_length / 1024 / 1024, 2) AS table_size_mb, + ROUND(index_length / 1024 / 1024, 2) AS indexes_size_mb, + ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_size_mb +FROM information_schema.tables +WHERE table_schema = DATABASE() + AND table_name = 'annotation'; +``` + +For SQLite, check the database file size directly, as SQLite stores all tables in a single file. You can run the following command from your terminal: + +```bash +ls -lh +``` + +If your total size is several gigabytes or more, you should plan accordingly before upgrading. + +#### What should I do before upgrading? + +Before you upgrade, take the following steps: + +1. **Verify available disk space**: Ensure you have at least 2-3 times the current `annotation` table size available as free disk space on your database data volume. + +1. **Review your annotation data**: Consider whether you need to retain all historical annotations. + +1. **Clean up old annotations (optional)**: If you have annotations you don't need, remove them before upgrading. + +1. **Back up your database**: Always back up your Grafana database before performing an upgrade. For more information, refer to [Back up Grafana](#back-up-grafana). + +#### What should I do after upgrading? + +After successfully upgrading to Grafana v12.x, you can reclaim disk space by performing database maintenance operations during a maintenance window. + +For PostgreSQL, run a `VACUUM FULL` operation on the `annotation` table: + +```sql +VACUUM FULL annotation; +``` + +For MySQL, run an `OPTIMIZE TABLE` operation on the `annotation` table: + +```sql +OPTIMIZE TABLE annotation; +``` + +For SQLite, run a `VACUUM` operation on the database: + +```sql +VACUUM; +``` + +These operations require a lock on the table and may take significant time depending on the table size. Plan to run these during a low-traffic period. diff --git a/docs/sources/upgrade-guide/upgrade-v12.1/index.md b/docs/sources/upgrade-guide/upgrade-v12.1/index.md index 74095298c90..9a96c0cbc0a 100644 --- a/docs/sources/upgrade-guide/upgrade-v12.1/index.md +++ b/docs/sources/upgrade-guide/upgrade-v12.1/index.md @@ -20,3 +20,87 @@ weight: 499 {{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="" >}} ## Technical notes + +### Annotation table migration + +**Plan for increased disk usage when upgrading from Grafana v11.x** + +Upgrading from Grafana v11.x to Grafana v12.x triggers a full-table rewrite of the `annotation` table. The migration populates the new `dashboard_uid` column, which causes the database to rewrite the entire table and rebuild its indexes. + +Environments with large annotation datasets can experience significant temporary disk usage increase, which may lead to: + +- Rapid disk consumption on the database data volume +- Database migration failures (for example, "could not extend file: No space left on device") +- Grafana startup failures +- Extended downtime during the upgrade process + +#### How do I know if I'm affected? + +You're affected if you're upgrading from Grafana v11.x to v12.x and you have a large `annotation` table in your database. + +To check your annotation table size, connect to your database and check the table size. + +For PostgreSQL, run the following query: + +```sql +SELECT + pg_size_pretty(pg_relation_size('annotation')) AS table_size, + pg_size_pretty(pg_indexes_size('annotation')) AS indexes_size, + pg_size_pretty(pg_total_relation_size('annotation')) AS total_size; +``` + +For MySQL, run the following query: + +```sql +SELECT + ROUND(data_length / 1024 / 1024, 2) AS table_size_mb, + ROUND(index_length / 1024 / 1024, 2) AS indexes_size_mb, + ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_size_mb +FROM information_schema.tables +WHERE table_schema = DATABASE() + AND table_name = 'annotation'; +``` + +For SQLite, check the database file size directly, as SQLite stores all tables in a single file. You can run the following command from your terminal: + +```bash +ls -lh +``` + +If your total size is several gigabytes or more, you should plan accordingly before upgrading. + +#### What should I do before upgrading? + +Before you upgrade, take the following steps: + +1. **Verify available disk space**: Ensure you have at least 2-3 times the current `annotation` table size available as free disk space on your database data volume. + +1. **Review your annotation data**: Consider whether you need to retain all historical annotations. + +1. **Clean up old annotations (optional)**: If you have annotations you don't need, remove them before upgrading. + +1. **Back up your database**: Always back up your Grafana database before performing an upgrade. For more information, refer to [Back up Grafana](#back-up-grafana). + +#### What should I do after upgrading? + +After successfully upgrading to Grafana v12.x, you can reclaim disk space by performing database maintenance operations during a maintenance window. + +For PostgreSQL, run a `VACUUM FULL` operation on the `annotation` table: + +```sql +VACUUM FULL annotation; +``` + +For MySQL, run an `OPTIMIZE TABLE` operation on the `annotation` table: + +```sql +OPTIMIZE TABLE annotation; +``` + +For SQLite, run a `VACUUM` operation on the database: + +```sql +VACUUM; +``` + +These operations require a lock on the table and may take significant time depending on the table size. Plan to run these during a low-traffic period. diff --git a/docs/sources/upgrade-guide/upgrade-v12.2/index.md b/docs/sources/upgrade-guide/upgrade-v12.2/index.md index d2605fc51d1..221ae3f152c 100644 --- a/docs/sources/upgrade-guide/upgrade-v12.2/index.md +++ b/docs/sources/upgrade-guide/upgrade-v12.2/index.md @@ -18,3 +18,89 @@ weight: 498 {{< docs/shared lookup="back-up/back-up-grafana.md" source="grafana" version="" leveloffset="+1" >}} {{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="" >}} + +## Technical notes + +### Annotation table migration + +**Plan for increased disk usage when upgrading from Grafana v11.x** + +Upgrading from Grafana v11.x to Grafana v12.x triggers a full-table rewrite of the `annotation` table. The migration populates the new `dashboard_uid` column, which causes the database to rewrite the entire table and rebuild its indexes. + +Environments with large annotation datasets can experience significant temporary disk usage increase, which may lead to: + +- Rapid disk consumption on the database data volume +- Database migration failures (for example, "could not extend file: No space left on device") +- Grafana startup failures +- Extended downtime during the upgrade process + +#### How do I know if I'm affected? + +You're affected if you're upgrading from Grafana v11.x to v12.x and you have a large `annotation` table in your database. + +To check your annotation table size, connect to your database and check the table size. + +For PostgreSQL, run the following query: + +```sql +SELECT + pg_size_pretty(pg_relation_size('annotation')) AS table_size, + pg_size_pretty(pg_indexes_size('annotation')) AS indexes_size, + pg_size_pretty(pg_total_relation_size('annotation')) AS total_size; +``` + +For MySQL, run the following query: + +```sql +SELECT + ROUND(data_length / 1024 / 1024, 2) AS table_size_mb, + ROUND(index_length / 1024 / 1024, 2) AS indexes_size_mb, + ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_size_mb +FROM information_schema.tables +WHERE table_schema = DATABASE() + AND table_name = 'annotation'; +``` + +For SQLite, check the database file size directly, as SQLite stores all tables in a single file. You can run the following command from your terminal: + +```bash +ls -lh +``` + +If your total size is several gigabytes or more, you should plan accordingly before upgrading. + +#### What should I do before upgrading? + +Before you upgrade, take the following steps: + +1. **Verify available disk space**: Ensure you have at least 2-3 times the current `annotation` table size available as free disk space on your database data volume. + +1. **Review your annotation data**: Consider whether you need to retain all historical annotations. + +1. **Clean up old annotations (optional)**: If you have annotations you don't need, remove them before upgrading. + +1. **Back up your database**: Always back up your Grafana database before performing an upgrade. For more information, refer to [Back up Grafana](#back-up-grafana). + +#### What should I do after upgrading? + +After successfully upgrading to Grafana v12.x, you can reclaim disk space by performing database maintenance operations during a maintenance window. + +For PostgreSQL, run a `VACUUM FULL` operation on the `annotation` table: + +```sql +VACUUM FULL annotation; +``` + +For MySQL, run an `OPTIMIZE TABLE` operation on the `annotation` table: + +```sql +OPTIMIZE TABLE annotation; +``` + +For SQLite, run a `VACUUM` operation on the database: + +```sql +VACUUM; +``` + +These operations require a lock on the table and may take significant time depending on the table size. Plan to run these during a low-traffic period. diff --git a/docs/sources/upgrade-guide/upgrade-v12.3/index.md b/docs/sources/upgrade-guide/upgrade-v12.3/index.md index 8d3dacbf396..6160c443e10 100644 --- a/docs/sources/upgrade-guide/upgrade-v12.3/index.md +++ b/docs/sources/upgrade-guide/upgrade-v12.3/index.md @@ -18,3 +18,89 @@ weight: 497 {{< docs/shared lookup="back-up/back-up-grafana.md" source="grafana" version="" leveloffset="+1" >}} {{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="" >}} + +## Technical notes + +### Annotation table migration + +**Plan for increased disk usage when upgrading from Grafana v11.x** + +Upgrading from Grafana v11.x to Grafana v12.x triggers a full-table rewrite of the `annotation` table. The migration populates the new `dashboard_uid` column, which causes the database to rewrite the entire table and rebuild its indexes. + +Environments with large annotation datasets can experience significant temporary disk usage increase, which may lead to: + +- Rapid disk consumption on the database data volume +- Database migration failures (for example, "could not extend file: No space left on device") +- Grafana startup failures +- Extended downtime during the upgrade process + +#### How do I know if I'm affected? + +You're affected if you're upgrading from Grafana v11.x to v12.x and you have a large `annotation` table in your database. + +To check your annotation table size, connect to your database and check the table size. + +For PostgreSQL, run the following query: + +```sql +SELECT + pg_size_pretty(pg_relation_size('annotation')) AS table_size, + pg_size_pretty(pg_indexes_size('annotation')) AS indexes_size, + pg_size_pretty(pg_total_relation_size('annotation')) AS total_size; +``` + +For MySQL, run the following query: + +```sql +SELECT + ROUND(data_length / 1024 / 1024, 2) AS table_size_mb, + ROUND(index_length / 1024 / 1024, 2) AS indexes_size_mb, + ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_size_mb +FROM information_schema.tables +WHERE table_schema = DATABASE() + AND table_name = 'annotation'; +``` + +For SQLite, check the database file size directly, as SQLite stores all tables in a single file. You can run the following command from your terminal: + +```bash +ls -lh +``` + +If your total size is several gigabytes or more, you should plan accordingly before upgrading. + +#### What should I do before upgrading? + +Before you upgrade, take the following steps: + +1. **Verify available disk space**: Ensure you have at least 2-3 times the current `annotation` table size available as free disk space on your database data volume. + +1. **Review your annotation data**: Consider whether you need to retain all historical annotations. + +1. **Clean up old annotations (optional)**: If you have annotations you don't need, remove them before upgrading. + +1. **Back up your database**: Always back up your Grafana database before performing an upgrade. For more information, refer to [Back up Grafana](#back-up-grafana). + +#### What should I do after upgrading? + +After successfully upgrading to Grafana v12.x, you can reclaim disk space by performing database maintenance operations during a maintenance window. + +For PostgreSQL, run a `VACUUM FULL` operation on the `annotation` table: + +```sql +VACUUM FULL annotation; +``` + +For MySQL, run an `OPTIMIZE TABLE` operation on the `annotation` table: + +```sql +OPTIMIZE TABLE annotation; +``` + +For SQLite, run a `VACUUM` operation on the database: + +```sql +VACUUM; +``` + +These operations require a lock on the table and may take significant time depending on the table size. Plan to run these during a low-traffic period. diff --git a/docs/sources/upgrade-guide/when-to-upgrade/index.md b/docs/sources/upgrade-guide/when-to-upgrade/index.md index e7a29e531e0..53d8c23330e 100644 --- a/docs/sources/upgrade-guide/when-to-upgrade/index.md +++ b/docs/sources/upgrade-guide/when-to-upgrade/index.md @@ -107,8 +107,8 @@ Here is an overview of version support through 2026: | 12.0.x | May 5, 2025 | February 5, 2026 | Patch Support | | 12.1.x | July 22, 2025 | April 22, 2026 | Patch Support | | 12.2.x | September 23, 2025 | June 23, 2026 | Patch Support | -| 12.3.x | November 18, 2025 | August 18, 2026 | Yet to be released | -| 12.4.x (Last minor of 12) | February 24, 2026 | November 24, 2026 | Yet to be released | +| 12.3.x | November 19, 2025 | August 19, 2026 | Patch Support | +| 12.4.x (Last minor of 12) | February 24, 2026 | May 24, 2027 | Yet to be released | | 13.0.0 | TBD | TBD | Yet to be released | ## How are these versions supported? diff --git a/docs/sources/visualizations/dashboards/build-dashboards/annotate-visualizations/index.md b/docs/sources/visualizations/dashboards/build-dashboards/annotate-visualizations/index.md index fcccfa6bd1b..5458f90281e 100644 --- a/docs/sources/visualizations/dashboards/build-dashboards/annotate-visualizations/index.md +++ b/docs/sources/visualizations/dashboards/build-dashboards/annotate-visualizations/index.md @@ -149,7 +149,10 @@ To add a new annotation query to a dashboard, follow these steps: You can also click **Open advanced data source picker** to see more options, including adding a data source (Admins only). 1. If you don't want to use the annotation query right away, clear the **Enabled** checkbox. -1. If you don't want the annotation query toggle to be displayed in the dashboard, select the **Hidden** checkbox. +1. Select one of the following options in the **Show annotation controls in** drop-down list to control where annotations are displayed: + - **Above dashboard** - The annotation toggle is displayed above the dashboard. This is the default. + - **Controls menu** - The annotation toggle is displayed in the dashboard controls menu instead of above the dashboard. The dashboard controls menu appears as a button in the dashboard toolbar. + - **Hidden** - The annotation toggle is not displayed on the dashboard. 1. Select a color for the event markers. 1. In the **Show in** drop-down, choose one of the following options: - **All panels** - The annotations are displayed on all panels that support annotations. @@ -160,9 +163,9 @@ To add a new annotation query to a dashboard, follow these steps: 1. To create a query, do one of the following: - Write or construct a query in the query language of your data source. The annotation query options are different for each data source. For information about annotations in a specific data source, refer to the specific [data source](ref:data-source) topic. - - Click **Replace with saved query** to reuse a [saved query](ref:saved-queries). + - Open the **Saved queries** drop-down menu and click **Replace query** to reuse a [saved query](ref:saved-queries). -1. (Optional) To [save the query](ref:save-query) for reuse, click the **Save query** button (or icon). +1. (Optional) To [save the query](ref:save-query) for reuse, open the **Saved queries** drop-down menu and click the **Save query** option. 1. (Optional) Click **Test annotation query** to ensure that the query is working properly. 1. (Optional) To add subsequent queries, click **+ Add query** or **+ Add from saved queries**, and test them as many times as needed. diff --git a/docs/sources/visualizations/dashboards/build-dashboards/create-dashboard/index.md b/docs/sources/visualizations/dashboards/build-dashboards/create-dashboard/index.md index feb6573c3e9..10196a40811 100644 --- a/docs/sources/visualizations/dashboards/build-dashboards/create-dashboard/index.md +++ b/docs/sources/visualizations/dashboards/build-dashboards/create-dashboard/index.md @@ -99,7 +99,7 @@ Dashboards and panels allow you to show your data in visual form. Each panel nee - Understand the query language of the target data source. - Ensure that data source for which you are writing a query has been added. For more information about adding a data source, refer to [Add a data source](ref:add-a-data-source) if you need instructions. -**To create a dashboard**: +To create a dashboard, follow these steps: {{< shared id="create-dashboard" >}} @@ -125,9 +125,9 @@ Dashboards and panels allow you to show your data in visual form. Each panel nee 1. To create a query, do one of the following: - Write or construct a query in the query language of your data source. - - Click **Replace with saved query** to reuse a [saved query](ref:saved-queries). + - Open the **Saved queries** drop-down menu and click **Replace query** to reuse a [saved query](ref:saved-queries). -1. (Optional) To [save the query](ref:save-query) for reuse, click the **Save query** button (or icon). +1. (Optional) To [save the query](ref:save-query) for reuse, open the **Saved queries** drop-down menu and click the **Save query** option. 1. Click **Refresh** to query the data source. 1. (Optional) To add subsequent queries, click **+ Add query** or **+ Add from saved queries**, and refresh the data source as many times as needed. @@ -171,6 +171,28 @@ Dashboards and panels allow you to show your data in visual form. Each panel nee Now, when you want to make more changes to the saved dashboard, click **Edit** in the top-right corner. +### Begin dashboard creation from data source configuration + +You can start the process of creating a dashboard directly from a data source rather than from the **Dashboards** page. + +To begin building a dashboard directly from a data source, follow these steps: + +1. Navigate to **Connections > Data sources**. +1. On the row of the data source for which you want to build a dashboard, click **Build a dashboard**. + + The empty dashboard page opens. + +1. Do one of the following: + - Click **+Add visualization** to configure all the elements of the new dashboard. + - Select one of the suggested dashboards by clicking its **Use dashboard** button. This can be helpful when you're not sure how to most effectively visualize your data. + The suggested dashboards are specific to your data source type (for example, Prometheus, Loki, or Elasticsearch). If there are more than three dashboard suggestions, you can click **View all** to see the rest of them. + + ![Empty dashboard with add visualization and suggested dashboard options](/media/docs/grafana/dashboards/screenshot-suggested-dashboards-v12.3.png) + + {{< docs/public-preview product="Suggested dashboards" >}} + +1. Complete the rest of the dashboard configuration. For more detailed steps, refer to [Create a dashboard](#create-a-dashboard), beginning at step five. + ## Copy a dashboard To copy a dashboard, follow these steps: diff --git a/docs/sources/visualizations/dashboards/build-dashboards/create-dynamic-dashboard/index.md b/docs/sources/visualizations/dashboards/build-dashboards/create-dynamic-dashboard/index.md index a77e4ca988f..0167ff147e5 100644 --- a/docs/sources/visualizations/dashboards/build-dashboards/create-dynamic-dashboard/index.md +++ b/docs/sources/visualizations/dashboards/build-dashboards/create-dynamic-dashboard/index.md @@ -245,11 +245,12 @@ To configure repeats, follow these steps: 1. Click **Save**. 1. Toggle off the edit mode switch. -### Repeating rows and the Dashboard special data source +### Repeating rows and tabs and the Dashboard special data source If a row includes panels using the special [Dashboard data source](ref:built-in-special-data-sources)—the data source that uses a result set from another panel in the same dashboard—then corresponding panels in repeated rows will reference the panel in the original row, not the ones in the repeated rows. +The same behavior applies to tabs. For example, in a dashboard: diff --git a/docs/sources/visualizations/dashboards/build-dashboards/manage-dashboard-links/index.md b/docs/sources/visualizations/dashboards/build-dashboards/manage-dashboard-links/index.md index cddf9a5b9f5..3e94ec5aa22 100644 --- a/docs/sources/visualizations/dashboards/build-dashboards/manage-dashboard-links/index.md +++ b/docs/sources/visualizations/dashboards/build-dashboards/manage-dashboard-links/index.md @@ -99,6 +99,7 @@ Add links to other dashboards at the top of your current dashboard. - **Include current time range** – Select this option to include the dashboard time range in the link. When the user clicks the link, the linked dashboard opens with the indicated time range already set. **Example:** https://play.grafana.org/d/000000010/annotations?orgId=1&from=now-3h&to=now - **Include current template variable values** – Select this option to include template variables currently used as query parameters in the link. When the user clicks the link, any matching templates in the linked dashboard are set to the values from the link. For more information, see [Dashboard URL variables](ref:dashboard-url-variables). - **Open link in new tab** – Select this option if you want the dashboard link to open in a new tab or window. + - **Show in controls menu** – Select this option to display the link in the dashboard controls menu instead of at the top of the dashboard. The dashboard controls menu appears as a button in the dashboard toolbar. 1. Click **Save dashboard** in the top-right corner. 1. Click **Back to dashboard** and then **Exit edit**. @@ -121,6 +122,7 @@ Add a link to a URL at the top of your current dashboard. You can link to any av - **Include current time range** – Select this option to include the dashboard time range in the link. When the user clicks the link, the linked dashboard opens with the indicated time range already set. **Example:** https://play.grafana.org/d/000000010/annotations?orgId=1&from=now-3h&to=now - **Include current template variable values** – Select this option to include template variables currently used as query parameters in the link. When the user clicks the link, any matching templates in the linked dashboard are set to the values from the link. - **Open link in new tab** – Select this option if you want the dashboard link to open in a new tab or window. + - **Show in controls menu** – Select this option to display the link in the dashboard controls menu instead of at the top of the dashboard. The dashboard controls menu appears as a button in the dashboard toolbar. 1. Click **Save dashboard** in the top-right corner. 1. Click **Back to dashboard** and then **Exit edit**. diff --git a/docs/sources/visualizations/dashboards/manage-dashboards/index.md b/docs/sources/visualizations/dashboards/manage-dashboards/index.md index f42892d4f39..b65fcecd758 100644 --- a/docs/sources/visualizations/dashboards/manage-dashboards/index.md +++ b/docs/sources/visualizations/dashboards/manage-dashboards/index.md @@ -124,6 +124,8 @@ For more information about dashboard permissions, refer to [Dashboard permission ## Restore deleted dashboards {{% admonition type="caution" %}} +Restoring deleted dashboards is currently in private preview. Grafana Labs offers support on a best-effort basis, and breaking changes might occur prior to the feature being made generally available. + The feature is only available in Grafana Cloud. {{% /admonition %}} diff --git a/docs/sources/visualizations/dashboards/share-dashboards-panels/_index.md b/docs/sources/visualizations/dashboards/share-dashboards-panels/_index.md index a2867759119..e7749ba5b88 100644 --- a/docs/sources/visualizations/dashboards/share-dashboards-panels/_index.md +++ b/docs/sources/visualizations/dashboards/share-dashboards-panels/_index.md @@ -98,7 +98,7 @@ You can share dashboards in the following ways: - [As a report](#schedule-a-report) - [As a snapshot](#share-a-snapshot) - [As a PDF export](#export-a-dashboard-as-pdf) -- [As a JSON file export](#export-a-dashboard-as-json) +- [As a JSON file export](#export-a-dashboard-as-code) - [As an image export](#export-a-dashboard-as-an-image) When you share a dashboard externally as a link or by email, those dashboards are included in a list of your shared dashboards. To view the list and manage these dashboards, navigate to **Dashboards > Shared dashboards**. @@ -223,17 +223,25 @@ To export a dashboard in its current state as a PDF, follow these steps: 1. Click the **X** at the top-right corner to close the share drawer. -### Export a dashboard as JSON +### Export a dashboard as code Export a Grafana JSON file that contains everything you need, including layout, variables, styles, data sources, queries, and so on, so that you can later import the dashboard. To export a JSON file, follow these steps: 1. Click **Dashboards** in the main menu. 1. Open the dashboard you want to export. -1. Click the **Export** drop-down list in the top-right corner and select **Export as JSON**. +1. Click the **Export** drop-down list in the top-right corner and select **Export as code**. - The **Export dashboard JSON** drawer opens. + The **Export dashboard** drawer opens. + +1. Select the dashboard JSON model that you to export: + - **Classic** - Export dashboards created using the [current dashboard schema](https://grafana.com/docs/grafana//visualizations/dashboards/build-dashboards/view-dashboard-json-model/). + - **V1 Resource** - Export dashboards created using the [current dashboard schema](https://grafana.com/docs/grafana//visualizations/dashboards/build-dashboards/view-dashboard-json-model/) wrapped in the `spec` property of the [V1 Kubernetes-style resource](https://play.grafana.org/swagger?api=dashboard.grafana.app-v2alpha1). Choose between **JSON** and **YAML** format. + - **V2 Resource** - Export dashboards created using the [V2 Resource schema](https://play.grafana.org/swagger?api=dashboard.grafana.app-v2beta1). Choose between **JSON** and **YAML** format. + +1. Do one of the following: + - Toggle the **Export for sharing externally** switch to generate the JSON with a different data source UID. + - Toggle the **Remove deployment details** switch to make the dashboard externally shareable. -1. Toggle the **Export the dashboard to use in another instance** switch to generate the JSON with a different data source UID. 1. Click **Download file** or **Copy to clipboard**. 1. Click the **X** at the top-right corner to close the share drawer. diff --git a/docs/sources/visualizations/dashboards/share-dashboards-panels/shared-dashboards/index.md b/docs/sources/visualizations/dashboards/share-dashboards-panels/shared-dashboards/index.md index a96efda3edf..b0dc5e723b2 100644 --- a/docs/sources/visualizations/dashboards/share-dashboards-panels/shared-dashboards/index.md +++ b/docs/sources/visualizations/dashboards/share-dashboards-panels/shared-dashboards/index.md @@ -37,6 +37,11 @@ refs: destination: /docs/grafana//introduction/grafana-enterprise/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//introduction/grafana-enterprise/ + fixed-role-definitions: + - pattern: /docs/grafana/ + destination: /docs/grafana//administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/#fixed-role-definitions + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-control/rbac-fixed-basic-role-definitions/#fixed-role-definitions --- # Externally shared dashboards @@ -49,6 +54,8 @@ Externally shared dashboards allow you to share your Grafana dashboard with anyo If you change a dashboard, ensure that you save the changes before sharing. +In order to create public dashboards, you need to be an Admin, have the `dashboards.public:write` permission, or the `fixed:dashboards.public:write` [RBAC role](ref:fixed-role-definitions). + {{< admonition type="warning" >}} Sharing your dashboard externally could result in a large number of queries to the data sources used by your dashboard. This can be mitigated by using the Enterprise [caching](ref:caching) and/or rate limiting features. diff --git a/docs/sources/visualizations/dashboards/variables/add-template-variables/index.md b/docs/sources/visualizations/dashboards/variables/add-template-variables/index.md index 69dbf4a2547..5ee61394a15 100644 --- a/docs/sources/visualizations/dashboards/variables/add-template-variables/index.md +++ b/docs/sources/visualizations/dashboards/variables/add-template-variables/index.md @@ -123,10 +123,11 @@ To create a variable, follow these steps: If you don't enter a display name, then the drop-down list label is the variable name. -1. Choose a **Show on dashboard** option: - - **Label and value** - The variable drop-down list displays the variable **Name** or **Label** value. This is the default. - - **Value:** The variable drop-down list only displays the selected variable value and a down arrow. - - **Nothing:** No variable drop-down list is displayed on the dashboard. +1. Choose a **Display** option: + - **Above dashboard** - The variable drop-down list displays above the dashboard with the variable **Name** or **Label** value. This is the default. + - **Above dashboard, label hidden** - The variable drop-down list displays above the dashboard, but without showing the name of the variable. + - **Controls menu** - The variable is displayed in the dashboard controls menu instead of above the dashboard. The dashboard controls menu appears as a button in the dashboard toolbar. + - **Hidden** - No variable drop-down list is displayed on the dashboard. 1. Click one of the following links to complete the steps for adding your selected variable type: - [Query](#add-a-query-variable) @@ -171,6 +172,7 @@ Query expressions are different for each data source. For more information, refe - If you need more room in a single input field query editor, then hover your cursor over the lines in the lower right corner of the field and drag downward to expand. 1. (Optional) In the **Regex** field, type a regular expression to filter or capture specific parts of the names returned by your data source query. To see examples, refer to [Filter variables with a regular expression](#filter-variables-with-regex). +1. Under **Apply regex to**, select **Variable value** or **Display text** to choose where the regex pattern is applied. The default is **Variable value**. 1. In the **Sort** drop-down list, select the sort order for values to be displayed in the dropdown list. The default option, **Disabled**, means that the order of options returned by your data source query is used. 1. Under **Refresh**, select when the variable should update options: - **On dashboard load** - Queries the data source every time the dashboard loads. This slows down dashboard loading, because the variable query needs to be completed before dashboard can be initialized. diff --git a/docs/sources/visualizations/explore/get-started-with-explore.md b/docs/sources/visualizations/explore/get-started-with-explore.md index b59ac68c686..41f1f8c5c01 100644 --- a/docs/sources/visualizations/explore/get-started-with-explore.md +++ b/docs/sources/visualizations/explore/get-started-with-explore.md @@ -71,8 +71,9 @@ Explore consists of a toolbar, outline, query editor, the ability to add multipl - **Run query** - Click to run your query. - **Query editor** - Interface where you construct the query for a specific data source. Query editor elements differ based on data source. In order to run queries across multiple data sources you need to select **Mixed** from the data source picker. - - **Save query** - To [save the query](ref:save-query) for reuse, click the **Save query** button (or icon). - - **Replace with saved query** - Reuse a saved query. + - **Saved queries**: + - **Save query** - To [save the query](ref:save-query) for reuse, click the **Save query** button (or icon). + - **Replace query** - Reuse a saved query. - **+ Add query** - Add an additional query. - **+ Add from saved queries** - Add an additional query by reusing a saved query. diff --git a/docs/sources/visualizations/explore/logs-integration.md b/docs/sources/visualizations/explore/logs-integration.md index 8aa18f45616..a4f8fe7c64b 100644 --- a/docs/sources/visualizations/explore/logs-integration.md +++ b/docs/sources/visualizations/explore/logs-integration.md @@ -43,24 +43,36 @@ If the data source doesn't support loading the full range logs volume, the logs The following sections provide detailed explanations on how to visualize and interact with individual logs in Explore. -### Logs navigation +### Infinite scroll -Logs navigation, located at the right side of the log lines, can be used to easily request additional logs by clicking **Older logs** at the bottom of the navigation. This is especially useful when you reach the line limit and you want to see more logs. Each request run from the navigation displays in the navigation as separate page. Every page shows `from` and `to` timestamps of the incoming log lines. You can see previous results by clicking on each page. Explore caches the last five requests run from the logs navigation so you're not re-running the same queries when clicking on the pages, saving time and resources. + -![Navigate logs in Explore](/static/img/docs/explore/navigate-logs-8-0.png) +When you reach the bottom of the list of logs, you will see the message `Scroll to load more`. If you continue scrolling and the displayed logs are within the selected time interval, Grafana will load more logs. When the sort order is "newest first" you receive older logs, and when the sort order is "oldest first" you get newer logs. + + ### Visualization options You have the option to customize the display of logs and choose which columns to show. Following is a list of available options. -| Option | Description | -| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Time** | Shows or hides the time column. This is the timestamp associated with the log line as reported from the data source. | -| **Unique labels** | Shows or hides the unique labels column that includes only non-common labels. All common labels are displayed above. | -| **Wrap lines** | Set this to `true` if you want the display to use line wrapping. If set to `false`, it will result in horizontal scrolling. | -| **Prettify JSON** | Set this to `true` to pretty print all JSON logs. This setting does not affect logs in any format other than JSON. | -| **Deduplication** | Log data can be very repetitive. Explore hides duplicate log lines using a few different deduplication algorithms. **Exact** matches are done on the whole line except for date fields. **Numbers** matches are done on the line after stripping out numbers such as durations, IP addresses, and so on. **Signature** is the most aggressive deduplication as it strips all letters and numbers and matches on the remaining whitespace and punctuation. | -| **Display results order** | You can change the order of received logs from the default descending order (newest first) to ascending order (oldest first). | + + +| Option | Description | +| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Expand / Collapse | Expand or collapse the controls toolbar. | +| Scroll to bottom | Jump to the bottom of the logs table. | +| Oldest Logs First / Newest logs first | Sort direction (ascending or descending). | +| Search logs / Close search | Click to open/close the client side string search of the displayed logs result. | +| Deduplication | **None** does not perform any deduplication, **Exact** matches are done on the whole line except for date fields. **Numbers** matches are done on the line after stripping out numbers such as durations, IP addresses, and so on. **Signature** is the most aggressive deduplication as it strips all letters and numbers and matches on the remaining whitespace and punctuation. | +| Filter levels | Filter logs in display by log level: All levels, Info, Debut, Warning, Error. | +| Set Timestamp format | Hide timestamps (disabled), Show milliseconds timestamps, Show nanoseconds timestamps. | +| Set line wrap | Disable line wrapping, Enable line wrapping, Enable line wrapping and prettify JSON. | +| Enable highlighting | Plain text, Highlight text. | +| Font size | Small font (default), Large font. | +| Unescaped newlines | Only displayed if the logs contain unescaped new lines. Click to unescape and display as new lines. | +| Download logs | Plain text (txt), JavaScript Object Notation (JSON), Comma-separated values (CSV) | + + ### Download log lines @@ -143,16 +155,31 @@ Click the **eye icon** to select a subset of fields to visualize in the logs lis Each field has a **stats icon**, which displays ad-hoc statistics in relation to all displayed logs. +For data sources that support log types, such as Loki, instead of a single view containing all fields, fields will be displayed grouped by their type: Indexed Labels, Parsed fields, and Structured Metadata. + #### Links Grafana provides data links or correlations, allowing you to convert any part of a log message into an internal or external link. These links enable you to navigate to related data or external resources, offering a seamless and convenient way to explore additional information. {{< figure src="/static/img/docs/explore/data-link-9-4.png" max-width="800px" caption="Data link in Explore" >}} +#### Log details modes + +There are two modes available to view log details: + +- **Inline** The default, displays log details below the log line. +- **Sidebar** Displays log details in a sidebar view. + +No matter which display mode you are currently viewing, you can change it by clicking the mode control icon. + ### Log context Log context is a feature that displays additional lines of context surrounding a log entry that matches a specific search query. This helps in understanding the context of the log entry and is similar to the `-C` parameter in the `grep` command. +If you're using Loki for your logs, to modify your log context queries, you can use the Loki log context query editor at the top of the table. You can activate this editor by clicking the menu for the log line, and selecting **Show context**. Within the **Log Context** view, you have the option to modify your search by removing one or more label filters from the log stream. If your original query used a parser, you can refine your search by leveraging extracted label filters. + +Change the **Context time window** option to look for logs within a specific time interval around your log line. + Toggle **Wrap lines** if you encounter long lines of text that make it difficult to read and analyze the context around log entries. By enabling this toggle, Grafana automatically wraps long lines of text to fit within the visible width of the viewer, making the log entries easier to read and understand. Click **Open in split view** to execute the context query for a log entry in a split screen in the Explore view. Clicking this button opens a new Explore pane with the context query displayed alongside the log entry, making it easier to analyze and understand the surrounding context. diff --git a/docs/sources/visualizations/panels-visualizations/panel-editor-overview/index.md b/docs/sources/visualizations/panels-visualizations/panel-editor-overview/index.md index 4afbd8f71a6..f219f10a68a 100644 --- a/docs/sources/visualizations/panels-visualizations/panel-editor-overview/index.md +++ b/docs/sources/visualizations/panels-visualizations/panel-editor-overview/index.md @@ -88,8 +88,9 @@ The data section contains tabs where you enter queries, transform your data, and - **Queries** - Select your data source. You can also set or update the data source in existing dashboards using the drop-down menu in the **Queries** tab. - - **Save query** - To [save the query](ref:save-query) for reuse, click the **Save query** button (or icon). - - **Replace with saved query** - Reuse a saved query. + - **Saved queries**: + - **Save query** - To [save the query](ref:save-query) for reuse, click the **Save query** button (or icon). + - **Replace query** - Reuse a saved query. - **+ Add query** - Add an additional query. - **+ Add from saved queries** - Add an additional query by reusing a saved query. diff --git a/docs/sources/visualizations/panels-visualizations/query-transform-data/_index.md b/docs/sources/visualizations/panels-visualizations/query-transform-data/_index.md index b6c9471e3e3..0aafe41f524 100644 --- a/docs/sources/visualizations/panels-visualizations/query-transform-data/_index.md +++ b/docs/sources/visualizations/panels-visualizations/query-transform-data/_index.md @@ -156,17 +156,23 @@ In the **Saved queries** drawer, you can: - Edit a query title, description, tags, or the availability of the query to other users in your organization. By default, saved queries are locked for editing. - When you access the **Saved queries** drawer from Explore, you can use the **Edit in Explore** option to edit the body of a query. -To access your saved queries, click **+ Add from saved queries** or **Replace with saved query** in the query editor: +To access your saved queries, click **+ Add from saved queries** or open the **Saved queries** drop-down menu and click **Replace query** in the query editor: {{< figure src="/media/docs/grafana/dashboards/screenshot-use-saved-queries-v12.3.png" max-width="750px" alt="Access saved queries" >}} -Clicking **+ Add from saved queries** adds an additional query, while clicking **Replace with saved query** updates your existing query. +Clicking **+ Add from saved queries** adds an additional query, while clicking **Replace query** in the **Saved queries** drop-down menu updates your existing query. + +{{< admonition type="note" >}} +Users with Admin and Editor roles can create and save queries for reuse. +While Admin users can edit or delete any saved queries, users with the Editor role can only edit or delete the queries they've saved. +Viewers can only reuse queries. +{{< /admonition >}} #### Save a query To save a query you've created: -1. From the query editor, click the **Save query** icon: +1. From the query editor, open the **Saved queries** drop-down menu and click the **Save query** option: {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-save-query-v12.2.png" max-width="750px" alt="Save a query" >}} @@ -221,7 +227,7 @@ To add a query, follow these steps: 1. To create a query, do one of the following: - Write or construct a query in the query language of your data source. - - Click **Replace with saved query** to reuse a saved query. + - Open the **Saved queries** drop-down menu and click **Replace query** to reuse a saved query. {{< admonition type="note" >}} [Saved queries](#saved-queries) is currently in [public preview](https://grafana.com/docs/release-life-cycle/). Grafana Labs offers limited support, and breaking changes might occur prior to the feature being made generally available. @@ -229,7 +235,7 @@ To add a query, follow these steps: This feature is only available on Grafana Enterprise and Grafana Cloud. {{< /admonition >}} -1. (Optional) To [save the query](#save-a-query) for reuse, click the **Save query** button (or icon). +1. (Optional) To [save the query](#save-a-query) for reuse, click the **Save query** option in the **Saved queries** drop-down menu. 1. (Optional) Click **+ Add query** or **Add from saved queries** to add more queries as needed. 1. Click **Run queries**. diff --git a/docs/sources/visualizations/panels-visualizations/query-transform-data/transform-data/index.md b/docs/sources/visualizations/panels-visualizations/query-transform-data/transform-data/index.md index b6b3499b4d7..2a13836d246 100644 --- a/docs/sources/visualizations/panels-visualizations/query-transform-data/transform-data/index.md +++ b/docs/sources/visualizations/panels-visualizations/query-transform-data/transform-data/index.md @@ -12,12 +12,13 @@ comments: | To build this Markdown, do the following: $ cd /docs (from the root of the repository) - $ make sources/panels-visualizations/query-transform-data/transform-data/index.md + $ make sources/visualizations/panels-visualizations/query-transform-data/transform-data/index.md $ make docs Browse to http://localhost:3003/docs/grafana/latest/panels-visualizations/query-transform-data/transform-data/ Refer to ./docs/README.md "Content guidelines" for more information about editing and building these docs. + aliases: - ../../../panels/transform-data/ # /docs/grafana/next/panels/transform-data/ - ../../../panels/transform-data/about-transformation/ # /docs/grafana/next/panels/transform-data/about-transformation/ diff --git a/docs/sources/visualizations/panels-visualizations/visualizations/logs/index.md b/docs/sources/visualizations/panels-visualizations/visualizations/logs/index.md index 3af0eeda0d5..d3a93095e7a 100644 --- a/docs/sources/visualizations/panels-visualizations/visualizations/logs/index.md +++ b/docs/sources/visualizations/panels-visualizations/visualizations/logs/index.md @@ -31,7 +31,7 @@ refs: _Logs_ are structured records of events or messages generated by a system or application—that is, a series of text records with status updates from your system or app. They generally include timestamps, messages, and context information like the severity of the logged event. -The logs visualization displays these records from data sources that support logs, such as Elastic, Influx, and Loki. The logs visualization has colored indicators of log status, as well as collapsible log events that help you analyze the information generated. +The logs visualization displays these records from data sources that support logs, such as Elastic, Influx, and Loki. The logs visualization shows, by default, the timestamp, a colored string representing the log status, the log line body, as well as collapsible log events that help you analyze the information generated. {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-logs-v12.3.png" max-width="750px" alt="Logs visualization" >}} @@ -100,16 +100,16 @@ Use these settings to refine your visualization: | Option | Description | | --------------- | --------------- | -| Time | Show or hide the time column. This is the timestamp associated with the log line as reported from the data source. | +| Show timestamps | Show or hide the time column. This is the timestamp associated with the log line as reported from the data source. | | Unique labels | Show or hide the unique labels column, which shows only non-common labels. | -| Common labels | Show or hide the common labels. | | Wrap lines | Turn line wrapping on or off. | -| Enable logs highlighting | Experimental. Use a predefined coloring scheme to highlight relevant parts of the log lines. Subtle colors are added to the log lines to improve readability and help with identifying important information faster. | +| Prettify JSON | Toggle the switch on to pretty print all JSON logs. This setting does not affect logs in any format other than JSON. | +| Enable highlighting | Use a predefined syntax coloring grammar to highlight relevant parts of the log lines | | Enable log details | Toggle the switch on to see an extendable area with log details including labels and detected fields. Each field or label has a stats icon to display ad-hoc statistics in relation to all displayed logs. The default setting is on. | -| Log details panel mode | Choose to display the log details in a sidebar panel or inline, below the log line. The default mode depends on viewport size: the default mode for smaller viewports is inline, while for larger ones, it's sidebar. You can also change mode dynamically in the panel by clicking the mode control. | -| Enable infinite scrolling | Request more results by scrolling to the bottom of the logs list. When you reach the bottom of the list of logs, if you continue scrolling and the displayed logs are within the selected time interval, you can request to load more logs. When the sort order is **Newest first**, you receive older logs, and when the sort order is **Oldest first** you get newer logs. | -| Show controls | Display controls to jump to the last or first log line, and filter by log level. | -| Font size | Select between the **Default** font size and **Small** font sizes.| +| Log Details panel mode | Choose to display the log details in a sidebar panel or inline, below the log line. | +| Enable infinite scrolling | Request more results by scrolling to the bottom of the logs list. | +| Show controls | Display controls to jump to the last or first log line, and filters by log level | +| Font size | Select between the default font size and small font size. | | Deduplication | Hide log messages that are duplicates of others shown, according to your selected criteria. Choose from:
  • **Exact** - Ignoring ISO datetimes.
  • **Numerical** - Ignoring only those that differ by numbers such as IPs or latencies.
  • **Signatures** - Removing successive lines with identical punctuation and white space.
| | Order | Set whether to show results **Newest first** or **Oldest first**. | diff --git a/e2e-playwright/alerting-suite/saved-searches.spec.ts b/e2e-playwright/alerting-suite/saved-searches.spec.ts new file mode 100644 index 00000000000..28de805a5a1 --- /dev/null +++ b/e2e-playwright/alerting-suite/saved-searches.spec.ts @@ -0,0 +1,271 @@ +import { Page } from '@playwright/test'; + +import { test, expect } from '@grafana/plugin-e2e'; + +/** + * UI selectors for Saved Searches e2e tests. + * Each selector is a function that takes the page and returns a locator. + */ +const ui = { + // Main elements + savedSearchesButton: (page: Page) => page.getByRole('button', { name: /saved searches/i }), + dropdown: (page: Page) => page.getByRole('dialog', { name: /saved searches/i }), + searchInput: (page: Page) => page.getByTestId('search-query-input'), + + // Save functionality + saveButton: (page: Page) => page.getByRole('button', { name: /save current search/i }), + saveConfirmButton: (page: Page) => page.getByRole('button', { name: /^save$/i }), + saveNameInput: (page: Page) => page.getByPlaceholder(/enter a name/i), + + // Action menu + actionsButton: (page: Page) => page.getByRole('button', { name: /actions/i }), + renameMenuItem: (page: Page) => page.getByText(/rename/i), + deleteMenuItem: (page: Page) => page.getByText(/^delete$/i), + setAsDefaultMenuItem: (page: Page) => page.getByText(/set as default/i), + deleteConfirmButton: (page: Page) => page.getByRole('button', { name: /^delete$/i }), + + // Indicators + emptyState: (page: Page) => page.getByText(/no saved searches/i), + defaultIcon: (page: Page) => page.locator('[title="Default search"]'), + duplicateError: (page: Page) => page.getByText(/already exists/i), +}; + +/** + * Helper to clear saved searches storage. + * UserStorage uses localStorage as fallback, so we clear both potential keys. + */ +async function clearSavedSearches(page: Page) { + await page.evaluate(() => { + // Clear localStorage keys that might contain saved searches + // UserStorage stores under 'grafana.userstorage.alerting' pattern + const keysToRemove = Object.keys(localStorage).filter( + (key) => key.includes('alerting') && (key.includes('savedSearches') || key.includes('userstorage')) + ); + keysToRemove.forEach((key) => localStorage.removeItem(key)); + + // Also clear session storage visited flag + const sessionKeysToRemove = Object.keys(sessionStorage).filter((key) => key.includes('alerting')); + sessionKeysToRemove.forEach((key) => sessionStorage.removeItem(key)); + }); +} + +test.describe( + 'Alert Rules - Saved Searches', + { + tag: ['@alerting'], + }, + () => { + test.beforeEach(async ({ page }) => { + // Clear any saved searches from previous tests before navigating + await page.goto('/alerting/list'); + await clearSavedSearches(page); + await page.reload(); + }); + + test.afterEach(async ({ page }) => { + // Clean up saved searches after each test + await clearSavedSearches(page); + }); + + test('should display Saved searches button', async ({ page }) => { + await expect(ui.savedSearchesButton(page)).toBeVisible(); + }); + + test('should open dropdown when clicking Saved searches button', async ({ page }) => { + await ui.savedSearchesButton(page).click(); + + await expect(ui.dropdown(page)).toBeVisible(); + }); + + test('should show empty state when no saved searches exist', async ({ page }) => { + // Storage is cleared in beforeEach, so we should see empty state + await ui.savedSearchesButton(page).click(); + + await expect(ui.emptyState(page)).toBeVisible(); + }); + + test('should enable Save current search button when search query is entered', async ({ page }) => { + // Enter a search query + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + // Open saved searches + await ui.savedSearchesButton(page).click(); + + await expect(ui.saveButton(page)).toBeEnabled(); + }); + + test('should disable Save current search button when search query is empty', async ({ page }) => { + await ui.savedSearchesButton(page).click(); + + await expect(ui.saveButton(page)).toBeDisabled(); + }); + + test('should save a new search', async ({ page }) => { + // Enter a search query + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + // Open saved searches + await ui.savedSearchesButton(page).click(); + + // Click save button + await ui.saveButton(page).click(); + + // Enter name and save + await ui.saveNameInput(page).fill('My Firing Rules'); + await ui.saveConfirmButton(page).click(); + + // Verify the saved search appears in the list + await expect(page.getByText('My Firing Rules')).toBeVisible(); + }); + + test('should show validation error for duplicate name', async ({ page }) => { + // First save a search + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + await ui.savedSearchesButton(page).click(); + + await ui.saveButton(page).click(); + + await ui.saveNameInput(page).fill('Duplicate Test'); + await ui.saveConfirmButton(page).click(); + + // Try to save another with the same name + await ui.saveButton(page).click(); + await ui.saveNameInput(page).fill('Duplicate Test'); + await ui.saveConfirmButton(page).click(); + + // Verify validation error + await expect(ui.duplicateError(page)).toBeVisible(); + }); + + test('should apply a saved search', async ({ page }) => { + // Create a saved search first + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + await ui.savedSearchesButton(page).click(); + + await ui.saveButton(page).click(); + + await ui.saveNameInput(page).fill('Apply Test'); + await ui.saveConfirmButton(page).click(); + + // Clear the search + await ui.searchInput(page).clear(); + await ui.searchInput(page).press('Enter'); + + // Apply the saved search + await ui.savedSearchesButton(page).click(); + await page.getByRole('button', { name: /apply search.*apply test/i }).click(); + + // Verify the search input is updated + await expect(ui.searchInput(page)).toHaveValue('state:firing'); + }); + + test('should rename a saved search', async ({ page }) => { + // Create a saved search + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + await ui.savedSearchesButton(page).click(); + + await ui.saveButton(page).click(); + + await ui.saveNameInput(page).fill('Original Name'); + await ui.saveConfirmButton(page).click(); + + // Open action menu and click rename + await ui.actionsButton(page).click(); + await ui.renameMenuItem(page).click(); + + // Enter new name + const renameInput = page.getByDisplayValue('Original Name'); + await renameInput.clear(); + await renameInput.fill('Renamed Search'); + await page.keyboard.press('Enter'); + + // Verify the name was updated + await expect(page.getByText('Renamed Search')).toBeVisible(); + await expect(page.getByText('Original Name')).not.toBeVisible(); + }); + + test('should delete a saved search', async ({ page }) => { + // Create a saved search + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + await ui.savedSearchesButton(page).click(); + + await ui.saveButton(page).click(); + + await ui.saveNameInput(page).fill('To Delete'); + await ui.saveConfirmButton(page).click(); + + // Verify it was saved + await expect(page.getByText('To Delete')).toBeVisible(); + + // Open action menu and click delete + await ui.actionsButton(page).click(); + await ui.deleteMenuItem(page).click(); + + // Confirm delete + await ui.deleteConfirmButton(page).click(); + + // Verify it was deleted + await expect(page.getByText('To Delete')).not.toBeVisible(); + }); + + test('should set a search as default', async ({ page }) => { + // Create a saved search + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + await ui.savedSearchesButton(page).click(); + + await ui.saveButton(page).click(); + + await ui.saveNameInput(page).fill('Default Test'); + await ui.saveConfirmButton(page).click(); + + // Set as default + await ui.actionsButton(page).click(); + await ui.setAsDefaultMenuItem(page).click(); + + // Verify the star icon appears (indicating default) + await expect(ui.defaultIcon(page)).toBeVisible(); + }); + + test('should close dropdown when pressing Escape', async ({ page }) => { + await ui.savedSearchesButton(page).click(); + + await expect(ui.dropdown(page)).toBeVisible(); + + await page.keyboard.press('Escape'); + + await expect(ui.dropdown(page)).not.toBeVisible(); + }); + + test('should cancel save mode when pressing Escape', async ({ page }) => { + // Enter a search query + await ui.searchInput(page).fill('state:firing'); + await ui.searchInput(page).press('Enter'); + + await ui.savedSearchesButton(page).click(); + + // Start save mode + await ui.saveButton(page).click(); + + await expect(ui.saveNameInput(page)).toBeVisible(); + + // Press Escape to cancel + await page.keyboard.press('Escape'); + + // Verify we're back to list mode + await expect(ui.saveNameInput(page)).not.toBeVisible(); + await expect(ui.saveButton(page)).toBeVisible(); + }); + } +); diff --git a/e2e-playwright/dashboard-cujs/scope-redirect.spec.ts b/e2e-playwright/dashboard-cujs/scope-redirect.spec.ts index c0e6e55b5b0..952e8a3da63 100644 --- a/e2e-playwright/dashboard-cujs/scope-redirect.spec.ts +++ b/e2e-playwright/dashboard-cujs/scope-redirect.spec.ts @@ -8,6 +8,7 @@ test.use({ scopeFilters: true, groupByVariable: true, reloadDashboardsOnParamsChange: true, + useScopesNavigationEndpoint: true, }, }); @@ -61,31 +62,6 @@ test.describe('Scope Redirect Functionality', () => { }); }); - test('should fall back to scope navigation when no redirectUrl', async ({ page, gotoDashboardPage }) => { - const scopes = testScopesWithRedirect(); - - await test.step('Navigate to dashboard and open scopes selector', async () => { - await gotoDashboardPage({ uid: 'cuj-dashboard-1' }); - await openScopesSelector(page, scopes); - }); - - await test.step('Select scope without redirectUrl', async () => { - // Select the scope without redirectUrl directly - await selectScope(page, 'sn-redirect-fallback', scopes[1]); - }); - - await test.step('Apply scopes and verify fallback behavior', async () => { - await applyScopes(page, [scopes[1]]); - - // Should stay on current dashboard since no redirectUrl is provided - // The scope navigation fallback should not redirect (as per existing behavior) - await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/); - - // Verify the scope was applied - await expect(page).toHaveURL(/scopes=scope-sn-redirect-fallback/); - }); - }); - test('should not redirect when reloading page on dashboard not in dashboard list', async ({ page, gotoDashboardPage, @@ -171,4 +147,47 @@ test.describe('Scope Redirect Functionality', () => { await expect(page).not.toHaveURL(/scopes=/); }); }); + + test('should not redirect to redirectPath when on active scope navigation', async ({ page, gotoDashboardPage }) => { + const scopes = testScopesWithRedirect(); + + await test.step('Set up scope navigation to dashboard-1', async () => { + // First, apply a scope that creates scope navigation to dashboard-1 (without redirectPath) + await gotoDashboardPage({ uid: 'cuj-dashboard-1' }); + await openScopesSelector(page, scopes); + await selectScope(page, 'sn-redirect-setup', scopes[2]); + await applyScopes(page, [scopes[2]]); + + // Verify we're on dashboard-1 with the scope applied + await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/); + await expect(page).toHaveURL(/scopes=scope-sn-redirect-setup/); + }); + + await test.step('Navigate to dashboard-1 to be on active scope navigation', async () => { + // Navigate to dashboard-1 which is now a scope navigation target + await gotoDashboardPage({ + uid: 'cuj-dashboard-1', + queryParams: new URLSearchParams({ scopes: 'scope-sn-redirect-setup' }), + }); + + // Verify we're on dashboard-1 + await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/); + }); + + await test.step('Apply scope with redirectPath and verify no redirect', async () => { + // Now apply a different scope that has redirectPath + // Since we're on an active scope navigation, it should NOT redirect + await openScopesSelector(page, scopes); + await selectScope(page, 'sn-redirect-with-navigation', scopes[3]); + await applyScopes(page, [scopes[3]]); + + // Verify the new scope was applied + await expect(page).toHaveURL(/scopes=scope-sn-redirect-with-navigation/); + + // Since we're already on the active scope navigation (dashboard-1), + // we should NOT redirect to redirectPath (dashboard-3) + await expect(page).toHaveURL(/\/d\/cuj-dashboard-1/); + await expect(page).not.toHaveURL(/\/d\/cuj-dashboard-3/); + }); + }); }); diff --git a/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts index c35eb03bf84..ad954267c85 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboard-group-panels.spec.ts @@ -419,6 +419,9 @@ test.describe( // Select tabs layout await page.getByLabel('layout-selection-option-Tabs').click(); + // confirm layout change + await dashboardPage.getByGrafanaSelector(selectors.pages.ConfirmModal.delete).click(); + await expect(dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('New row'))).toBeVisible(); await expect(dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('New row 1'))).toBeVisible(); await expect( @@ -757,6 +760,9 @@ test.describe( // Select rows layout await page.getByLabel('layout-selection-option-Rows').click(); + // confirm layout change + await dashboardPage.getByGrafanaSelector(selectors.pages.ConfirmModal.delete).click(); + await dashboardPage .getByGrafanaSelector(selectors.components.DashboardRow.wrapper('New tab 1')) .scrollIntoViewIfNeeded(); diff --git a/e2e-playwright/dashboard-new-layouts/dashboard-keybindings.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboard-keybindings.spec.ts new file mode 100644 index 00000000000..867337ba088 --- /dev/null +++ b/e2e-playwright/dashboard-new-layouts/dashboard-keybindings.spec.ts @@ -0,0 +1,61 @@ +import { test, expect } from '@grafana/plugin-e2e'; + +test.use({ + featureToggles: { + kubernetesDashboards: true, + dashboardNewLayouts: true, + }, +}); + +test.describe('Dashboard keybindings with new layouts', { tag: ['@dashboards'] }, () => { + test.use({ + viewport: { width: 1280, height: 1080 }, + }); + + test('should collapse and expand all rows', async ({ gotoDashboardPage, page, selectors }) => { + const dashboardPage = await gotoDashboardPage({ uid: 'Repeating-rows-uid/repeating-rows' }); + + const panelContents = dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.content); + await expect(panelContents).toHaveCount(5); + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('server = A, pod = Bob')) + ).toBeVisible(); + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('server = B, pod = Bob')) + ).toBeVisible(); + + // Collapse all rows using keyboard shortcut: d + Shift+C + await page.keyboard.press('d'); + await page.keyboard.press('Shift+C'); + + await expect(panelContents).toHaveCount(0); + await expect(page.getByText('server = A, pod = Bob')).toBeHidden(); + await expect(page.getByText('server = B, pod = Bob')).toBeHidden(); + + // Expand all rows using keyboard shortcut: d + Shift+E + await page.keyboard.press('d'); + await page.keyboard.press('Shift+E'); + + await expect(panelContents).toHaveCount(6); + await expect(page.getByText('server = A, pod = Bob')).toBeVisible(); + await expect(page.getByText('server = B, pod = Bob')).toBeVisible(); + }); + + test('should open panel inspect', async ({ gotoDashboardPage, page, selectors }) => { + const dashboardPage = await gotoDashboardPage({ uid: 'edediimbjhdz4b/a-tall-dashboard' }); + + // Find Panel #1 and press 'i' to open inspector + const panel1 = dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel #1')); + await expect(panel1).toBeVisible(); + await panel1.press('i'); + + await expect(dashboardPage.getByGrafanaSelector(selectors.components.PanelInspector.Json.content)).toBeVisible(); + + // Press Escape to close tooltip on the close button + await page.keyboard.press('Escape'); + // Press Escape to close inspector + await page.keyboard.press('Escape'); + + await expect(page.getByTestId(selectors.components.PanelInspector.Json.content)).toBeHidden(); + }); +}); diff --git a/e2e-playwright/dashboard-new-layouts/dashboards-edit-variables.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboards-edit-variables.spec.ts index 4b5ea9574f8..15a41047fe6 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboards-edit-variables.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboards-edit-variables.spec.ts @@ -1,6 +1,6 @@ import { test, expect } from '@grafana/plugin-e2e'; -import { flows, type Variable } from './utils'; +import { flows, saveDashboard, type Variable } from './utils'; test.use({ featureToggles: { @@ -64,20 +64,7 @@ test.describe( label: 'VariableUnderTest', }; - // common steps to add a new variable - await flows.newEditPaneVariableClick(dashboardPage, selectors); - await flows.newEditPanelCommonVariableInputs(dashboardPage, selectors, variable); - - // set the textbox variable value - const type = 'variable-type Value'; - const fieldLabel = dashboardPage.getByGrafanaSelector( - selectors.components.PanelEditor.OptionsPane.fieldLabel(type) - ); - await expect(fieldLabel).toBeVisible(); - const inputField = fieldLabel.locator('input'); - await expect(inputField).toBeVisible(); - await inputField.fill(variable.value); - await inputField.blur(); + await flows.addNewTextBoxVariable(dashboardPage, variable); // select the variable in the dashboard and confirm the variable value is set await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItem).click(); @@ -140,5 +127,94 @@ test.describe( await expect(panelContent).toBeVisible(); await expect(markdownContent).toContainText('VariableUnderTest: 10m'); }); + test('can hide a variable', async ({ dashboardPage, selectors, page }) => { + const variable: Variable = { + type: 'textbox', + name: 'VariableUnderTest', + value: 'foo', + label: 'VariableUnderTest', + }; + + await saveDashboard(dashboardPage, page, selectors, 'can hide a variable'); + await flows.addNewTextBoxVariable(dashboardPage, variable); + + // check the variable is visible in the dashboard + const variableLabel = dashboardPage.getByGrafanaSelector( + selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label) + ); + await expect(variableLabel).toBeVisible(); + // hide the variable + await dashboardPage + .getByGrafanaSelector(selectors.pages.Dashboard.Settings.Variables.Edit.General.generalDisplaySelect) + .click(); + await page.getByText('Hidden', { exact: true }).click(); + + // check that the variable is still visible + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeVisible(); + + // save dashboard and exit edit mode and check variable is not visible + await saveDashboard(dashboardPage, page, selectors); + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeHidden(); + // refresh and check that variable isn't visible + await page.reload(); + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeHidden(); + // check that the variable is visible in edit mode + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeVisible(); + }); + + test('can hide variable under the controls menu', async ({ dashboardPage, selectors, page }) => { + const variable: Variable = { + type: 'textbox', + name: 'VariableUnderTest', + value: 'foo', + label: 'VariableUnderTest', + }; + await saveDashboard(dashboardPage, page, selectors, 'can hide a variable in controls menu'); + + await flows.addNewTextBoxVariable(dashboardPage, variable); + + // check the variable is visible in the dashboard + const variableLabel = dashboardPage.getByGrafanaSelector( + selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label) + ); + await expect(variableLabel).toBeVisible(); + // hide the variable + await dashboardPage + .getByGrafanaSelector(selectors.pages.Dashboard.Settings.Variables.Edit.General.generalDisplaySelect) + .click(); + await page.getByText('Controls menu', { exact: true }).click(); + + // check that the variable is hidden under the controls menu + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeHidden(); + await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.ControlsButton).click(); + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeVisible(); + + // save dashboard and refresh + await saveDashboard(dashboardPage, page, selectors); + await page.reload(); + + //check that the variable is hidden under the controls menu + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeHidden(); + await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.ControlsButton).click(); + await expect( + dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.SubMenu.submenuItemLabels(variable.label!)) + ).toBeVisible(); + }); } ); diff --git a/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts index ffacaa13912..803f9d18d46 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboards-panel-layouts.spec.ts @@ -4,6 +4,8 @@ import { test, expect, E2ESelectorGroups, DashboardPage } from '@grafana/plugin- import testV2Dashboard from '../dashboards/TestV2Dashboard.json'; +import { switchToAutoGrid } from './utils'; + test.use({ featureToggles: { kubernetesDashboards: true, @@ -33,7 +35,8 @@ test.describe( ).toHaveCount(3); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await page.getByLabel('layout-selection-option-Auto grid').click(); + + await switchToAutoGrid(page, dashboardPage); await expect( dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel')) @@ -64,7 +67,8 @@ test.describe( ).toHaveCount(3); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await page.getByLabel('layout-selection-option-Auto grid').click(); + + await switchToAutoGrid(page, dashboardPage); // Get initial positions - standard width should have panels on different rows const firstPanelTop = await getPanelTop(dashboardPage, selectors); @@ -124,7 +128,8 @@ test.describe( ).toHaveCount(3); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await page.getByLabel('layout-selection-option-Auto grid').click(); + + await switchToAutoGrid(page, dashboardPage); await dashboardPage .getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.minColumnWidth) @@ -181,7 +186,8 @@ test.describe( ).toHaveCount(3); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await page.getByLabel('layout-selection-option-Auto grid').click(); + + await switchToAutoGrid(page, dashboardPage); await dashboardPage .getByGrafanaSelector(selectors.components.PanelEditor.ElementEditPane.AutoGridLayout.maxColumns) @@ -216,7 +222,8 @@ test.describe( ).toHaveCount(3); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await page.getByLabel('layout-selection-option-Auto grid').click(); + + await switchToAutoGrid(page, dashboardPage); const regularRowHeight = await getPanelHeight(dashboardPage, selectors); @@ -271,7 +278,8 @@ test.describe( ).toHaveCount(3); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await page.getByLabel('layout-selection-option-Auto grid').click(); + + await switchToAutoGrid(page, dashboardPage); const regularRowHeight = await getPanelHeight(dashboardPage, selectors); @@ -328,7 +336,8 @@ test.describe( ).toHaveCount(3); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await page.getByLabel('layout-selection-option-Auto grid').click(); + + await switchToAutoGrid(page, dashboardPage); // Set narrow column width first to ensure panels fit horizontally await dashboardPage diff --git a/e2e-playwright/dashboard-new-layouts/dashboards-repeats-auto-grid.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboards-repeats-auto-grid.spec.ts index dbba5c583c1..3e25adc6c41 100644 --- a/e2e-playwright/dashboard-new-layouts/dashboards-repeats-auto-grid.spec.ts +++ b/e2e-playwright/dashboard-new-layouts/dashboards-repeats-auto-grid.spec.ts @@ -1,6 +1,6 @@ import { Page } from 'playwright-core'; -import { test, expect } from '@grafana/plugin-e2e'; +import { test, expect, DashboardPage } from '@grafana/plugin-e2e'; import testV2DashWithRepeats from '../dashboards/V2DashWithRepeats.json'; @@ -12,6 +12,7 @@ import { getPanelPosition, importTestDashboard, goToEmbeddedPanel, + switchToAutoGrid, } from './utils'; const repeatTitleBase = 'repeat - '; @@ -42,7 +43,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); await dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel')).first().click(); @@ -78,7 +79,8 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); + await saveDashboard(dashboardPage, page, selectors); await page.reload(); @@ -117,7 +119,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); // select first/original repeat panel to activate edit pane await dashboardPage @@ -148,7 +150,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); await saveDashboard(dashboardPage, page, selectors); await page.reload(); @@ -214,7 +216,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); await saveDashboard(dashboardPage, page, selectors); // loading directly into panel editor @@ -271,7 +273,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); // this moving repeated panel between two normal panels await movePanel(dashboardPage, selectors, `${repeatTitleBase}${repeatOptions.at(0)}`, 'New panel'); @@ -319,7 +321,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); await saveDashboard(dashboardPage, page, selectors); await page.reload(); @@ -382,7 +384,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); await saveDashboard(dashboardPage, page, selectors); await page.reload(); @@ -410,7 +412,7 @@ test.describe( await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); await dashboardPage.getByGrafanaSelector(selectors.pages.Dashboard.Sidebar.optionsButton).click(); - await switchToAutoGrid(page); + await switchToAutoGrid(page, dashboardPage); await saveDashboard(dashboardPage, page, selectors); await page.reload(); @@ -462,7 +464,3 @@ test.describe( }); } ); - -async function switchToAutoGrid(page: Page) { - await page.getByLabel('layout-selection-option-Auto grid').click(); -} diff --git a/e2e-playwright/dashboard-new-layouts/utils.ts b/e2e-playwright/dashboard-new-layouts/utils.ts index 83508063ef5..ade6825b7c1 100644 --- a/e2e-playwright/dashboard-new-layouts/utils.ts +++ b/e2e-playwright/dashboard-new-layouts/utils.ts @@ -1,5 +1,6 @@ import { Page } from '@playwright/test'; +import { selectors } from '@grafana/e2e-selectors'; import { DashboardPage, E2ESelectorGroups, expect } from '@grafana/plugin-e2e'; import testV2Dashboard from '../dashboards/TestV2Dashboard.json'; @@ -78,6 +79,20 @@ export const flows = { await variableLabelInput.blur(); } }, + async addNewTextBoxVariable(dashboardPage: DashboardPage, variable: Variable) { + await flows.newEditPaneVariableClick(dashboardPage, selectors); + await flows.newEditPanelCommonVariableInputs(dashboardPage, selectors, variable); + // set the textbox variable value + const type = 'variable-type Value'; + const fieldLabel = dashboardPage.getByGrafanaSelector( + selectors.components.PanelEditor.OptionsPane.fieldLabel(type) + ); + await expect(fieldLabel).toBeVisible(); + const inputField = fieldLabel.locator('input'); + await expect(inputField).toBeVisible(); + await inputField.fill(variable.value); + await inputField.blur(); + }, }; export type Variable = { @@ -88,8 +103,16 @@ export type Variable = { value: string; }; -export async function saveDashboard(dashboardPage: DashboardPage, page: Page, selectors: E2ESelectorGroups) { +export async function saveDashboard( + dashboardPage: DashboardPage, + page: Page, + selectors: E2ESelectorGroups, + title?: string +) { await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.saveButton).click(); + if (title) { + await page.getByTestId(selectors.components.Drawer.DashboardSaveDrawer.saveAsTitleInput).fill(title); + } await dashboardPage.getByGrafanaSelector(selectors.components.Drawer.DashboardSaveDrawer.saveButton).click(); await expect(page.getByText('Dashboard saved')).toBeVisible(); } @@ -239,3 +262,12 @@ export async function getTabPosition(dashboardPage: DashboardPage, selectors: E2 const boundingBox = await tab.boundingBox(); return boundingBox; } + +export async function switchToAutoGrid(page: Page, dashboardPage: DashboardPage) { + await page.getByLabel('layout-selection-option-Auto grid').click(); + // confirm layout change if applicable + const confirmModal = dashboardPage.getByGrafanaSelector(selectors.pages.ConfirmModal.delete); + if (confirmModal) { + await confirmModal.click(); + } +} diff --git a/e2e-playwright/dashboards-suite/dashboard-browse-nested.spec.ts b/e2e-playwright/dashboards-suite/dashboard-browse-nested.spec.ts index 6765d299e53..caa83bfdb90 100644 --- a/e2e-playwright/dashboards-suite/dashboard-browse-nested.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-browse-nested.spec.ts @@ -10,7 +10,7 @@ const NUM_NESTED_DASHBOARDS = 60; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-browse.spec.ts b/e2e-playwright/dashboards-suite/dashboard-browse.spec.ts index 8ae318bcefa..6949eca4555 100644 --- a/e2e-playwright/dashboards-suite/dashboard-browse.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-browse.spec.ts @@ -5,7 +5,7 @@ import testDashboard from '../dashboards/TestDashboard.json'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-export-image.spec.ts b/e2e-playwright/dashboards-suite/dashboard-export-image.spec.ts index a97a04a14b8..e15991514a2 100644 --- a/e2e-playwright/dashboards-suite/dashboard-export-image.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-export-image.spec.ts @@ -7,7 +7,7 @@ test.use({ scenes: true, sharingDashboardImage: true, // Enable the export image feature kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-export-json.spec.ts b/e2e-playwright/dashboards-suite/dashboard-export-json.spec.ts index 428193ab5fa..26a8fb61dc8 100644 --- a/e2e-playwright/dashboards-suite/dashboard-export-json.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-export-json.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-keybindings.spec.ts b/e2e-playwright/dashboards-suite/dashboard-keybindings.spec.ts index b0ecf44f9f1..dd83b3a0cfd 100644 --- a/e2e-playwright/dashboards-suite/dashboard-keybindings.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-keybindings.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); @@ -58,6 +58,8 @@ test.describe( await expect(dashboardPage.getByGrafanaSelector(selectors.components.PanelInspector.Json.content)).toBeVisible(); + // Press Escape to close tooltip on the close button + await page.keyboard.press('Escape'); // Press Escape to close inspector await page.keyboard.press('Escape'); diff --git a/e2e-playwright/dashboards-suite/dashboard-links-without-slug.spec.ts b/e2e-playwright/dashboards-suite/dashboard-links-without-slug.spec.ts index 0a982e148b5..ca05fd24160 100644 --- a/e2e-playwright/dashboards-suite/dashboard-links-without-slug.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-links-without-slug.spec.ts @@ -5,7 +5,7 @@ import testDashboard from '../dashboards/DataLinkWithoutSlugTest.json'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-live-streaming.spec.ts b/e2e-playwright/dashboards-suite/dashboard-live-streaming.spec.ts index 20f455ea3a8..b7e18e56b45 100644 --- a/e2e-playwright/dashboards-suite/dashboard-live-streaming.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-live-streaming.spec.ts @@ -5,7 +5,7 @@ import testDashboard from '../dashboards/DashboardLiveTest.json'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-public-create.spec.ts b/e2e-playwright/dashboards-suite/dashboard-public-create.spec.ts index fd5dc979d81..9653218f5ff 100644 --- a/e2e-playwright/dashboards-suite/dashboard-public-create.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-public-create.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', dashboardScene: false, // this test is for the old sharing modal only used when scenes is turned off }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-public-templating.spec.ts b/e2e-playwright/dashboards-suite/dashboard-public-templating.spec.ts index c59e323076d..9f15a740fcf 100644 --- a/e2e-playwright/dashboards-suite/dashboard-public-templating.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-public-templating.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', dashboardScene: false, // this test is for the old sharing modal only used when scenes is turned off }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-share-externally-create.spec.ts b/e2e-playwright/dashboards-suite/dashboard-share-externally-create.spec.ts index 3398e9aaa35..3827872c199 100644 --- a/e2e-playwright/dashboards-suite/dashboard-share-externally-create.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-share-externally-create.spec.ts @@ -4,7 +4,7 @@ test.use({ featureToggles: { scenes: true, kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-share-internally.spec.ts b/e2e-playwright/dashboards-suite/dashboard-share-internally.spec.ts index 26f8b85d13e..6ff1825f9cd 100644 --- a/e2e-playwright/dashboards-suite/dashboard-share-internally.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-share-internally.spec.ts @@ -4,7 +4,7 @@ test.use({ featureToggles: { scenes: true, kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-share-snapshot-create.spec.ts b/e2e-playwright/dashboards-suite/dashboard-share-snapshot-create.spec.ts index 1a7e03d6243..b5c77458121 100644 --- a/e2e-playwright/dashboards-suite/dashboard-share-snapshot-create.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-share-snapshot-create.spec.ts @@ -6,7 +6,7 @@ test.use({ featureToggles: { scenes: true, kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-templating.spec.ts b/e2e-playwright/dashboards-suite/dashboard-templating.spec.ts index 78c35dc5de7..0a4eb5d3a9a 100644 --- a/e2e-playwright/dashboards-suite/dashboard-templating.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-templating.spec.ts @@ -6,7 +6,7 @@ test.use({ timezoneId: 'Pacific/Easter', featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-time-zone.spec.ts b/e2e-playwright/dashboards-suite/dashboard-time-zone.spec.ts index 937224290b0..ee3de574512 100644 --- a/e2e-playwright/dashboards-suite/dashboard-time-zone.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-time-zone.spec.ts @@ -8,7 +8,7 @@ const TIMEZONE_DASHBOARD_UID = 'd41dbaa2-a39e-4536-ab2b-caca52f1a9c8'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/dashboard-timepicker.spec.ts b/e2e-playwright/dashboards-suite/dashboard-timepicker.spec.ts index 4ffd65b83a3..ae2f08b230f 100644 --- a/e2e-playwright/dashboards-suite/dashboard-timepicker.spec.ts +++ b/e2e-playwright/dashboards-suite/dashboard-timepicker.spec.ts @@ -17,7 +17,7 @@ test.use({ }, featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/embedded-dashboard.spec.ts b/e2e-playwright/dashboards-suite/embedded-dashboard.spec.ts index f457eddf19e..aad8ed3367a 100644 --- a/e2e-playwright/dashboards-suite/embedded-dashboard.spec.ts +++ b/e2e-playwright/dashboards-suite/embedded-dashboard.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/general-dashboards.spec.ts b/e2e-playwright/dashboards-suite/general-dashboards.spec.ts index 99f84cb6d9f..d3ba9d9046e 100644 --- a/e2e-playwright/dashboards-suite/general-dashboards.spec.ts +++ b/e2e-playwright/dashboards-suite/general-dashboards.spec.ts @@ -5,7 +5,7 @@ const PAGE_UNDER_TEST = 'edediimbjhdz4b/a-tall-dashboard'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/import-dashboard.spec.ts b/e2e-playwright/dashboards-suite/import-dashboard.spec.ts index 5fdca6954aa..f489f576887 100644 --- a/e2e-playwright/dashboards-suite/import-dashboard.spec.ts +++ b/e2e-playwright/dashboards-suite/import-dashboard.spec.ts @@ -5,7 +5,7 @@ import testDashboard from '../dashboards/TestDashboard.json'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/load-options-from-url.spec.ts b/e2e-playwright/dashboards-suite/load-options-from-url.spec.ts index ca06e31528a..08847be8d8e 100644 --- a/e2e-playwright/dashboards-suite/load-options-from-url.spec.ts +++ b/e2e-playwright/dashboards-suite/load-options-from-url.spec.ts @@ -5,7 +5,7 @@ const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/new-constant-variable.spec.ts b/e2e-playwright/dashboards-suite/new-constant-variable.spec.ts index fa0b5fc1bfd..0abd9d248f1 100644 --- a/e2e-playwright/dashboards-suite/new-constant-variable.spec.ts +++ b/e2e-playwright/dashboards-suite/new-constant-variable.spec.ts @@ -6,7 +6,7 @@ const DASHBOARD_NAME = 'Test variable output'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/new-custom-variable.spec.ts b/e2e-playwright/dashboards-suite/new-custom-variable.spec.ts index c14a952e1d9..79e545c9a41 100644 --- a/e2e-playwright/dashboards-suite/new-custom-variable.spec.ts +++ b/e2e-playwright/dashboards-suite/new-custom-variable.spec.ts @@ -53,7 +53,7 @@ async function assertPreviewValues( test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/new-datasource-variable.spec.ts b/e2e-playwright/dashboards-suite/new-datasource-variable.spec.ts index cc19e67cda4..03859ccc5ea 100644 --- a/e2e-playwright/dashboards-suite/new-datasource-variable.spec.ts +++ b/e2e-playwright/dashboards-suite/new-datasource-variable.spec.ts @@ -6,7 +6,7 @@ const DASHBOARD_NAME = 'Test variable output'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/new-interval-variable.spec.ts b/e2e-playwright/dashboards-suite/new-interval-variable.spec.ts index d76b5291c42..9c5cc8cc60f 100644 --- a/e2e-playwright/dashboards-suite/new-interval-variable.spec.ts +++ b/e2e-playwright/dashboards-suite/new-interval-variable.spec.ts @@ -19,7 +19,7 @@ async function assertPreviewValues( test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/new-query-variable.spec.ts b/e2e-playwright/dashboards-suite/new-query-variable.spec.ts index ed92c79ee36..96375f3fb97 100644 --- a/e2e-playwright/dashboards-suite/new-query-variable.spec.ts +++ b/e2e-playwright/dashboards-suite/new-query-variable.spec.ts @@ -6,7 +6,7 @@ const DASHBOARD_NAME = 'Templating - Nested Template Variables'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); @@ -79,6 +79,16 @@ test.describe( await expect(regexInput).toHaveAttribute('placeholder', '/.*-(?.*)-(?.*)-.*/'); await expect(regexInput).toHaveValue(''); + // Check regex apply to field - should default to "Variable value" + const regexApplyToField = dashboardPage.getByGrafanaSelector( + selectors.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsRegExApplyToSelectV2 + ); + await expect(regexApplyToField).toBeVisible(); + const variableValueRadio = page.getByRole('radio', { name: 'Variable value' }); + await expect(variableValueRadio).toBeChecked(); + const displayTextRadio = page.getByRole('radio', { name: 'Display text' }); + await expect(displayTextRadio).not.toBeChecked(); + const sortSelect = dashboardPage.getByGrafanaSelector( selectors.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsSortSelectV2 ); diff --git a/e2e-playwright/dashboards-suite/new-text-box-variable.spec.ts b/e2e-playwright/dashboards-suite/new-text-box-variable.spec.ts index c669dc563c4..ba3b9466e7d 100644 --- a/e2e-playwright/dashboards-suite/new-text-box-variable.spec.ts +++ b/e2e-playwright/dashboards-suite/new-text-box-variable.spec.ts @@ -6,7 +6,7 @@ const DASHBOARD_NAME = 'Test variable output'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/repeating-a-panel-horizontally.spec.ts b/e2e-playwright/dashboards-suite/repeating-a-panel-horizontally.spec.ts index a55f14b8643..413466972e1 100644 --- a/e2e-playwright/dashboards-suite/repeating-a-panel-horizontally.spec.ts +++ b/e2e-playwright/dashboards-suite/repeating-a-panel-horizontally.spec.ts @@ -5,7 +5,7 @@ const PAGE_UNDER_TEST = 'WVpf2jp7z/repeating-a-panel-horizontally'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/repeating-a-panel-vertically.spec.ts b/e2e-playwright/dashboards-suite/repeating-a-panel-vertically.spec.ts index bb188c87e8d..53966eadf05 100644 --- a/e2e-playwright/dashboards-suite/repeating-a-panel-vertically.spec.ts +++ b/e2e-playwright/dashboards-suite/repeating-a-panel-vertically.spec.ts @@ -5,7 +5,7 @@ const PAGE_UNDER_TEST = 'OY8Ghjt7k/repeating-a-panel-vertically'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/repeating-an-empty-row.spec.ts b/e2e-playwright/dashboards-suite/repeating-an-empty-row.spec.ts index e31c5792062..06c0e77989b 100644 --- a/e2e-playwright/dashboards-suite/repeating-an-empty-row.spec.ts +++ b/e2e-playwright/dashboards-suite/repeating-an-empty-row.spec.ts @@ -5,7 +5,7 @@ const PAGE_UNDER_TEST = 'dtpl2Ctnk/repeating-an-empty-row'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/set-options-from-ui.spec.ts b/e2e-playwright/dashboards-suite/set-options-from-ui.spec.ts index 53290345e73..629abda2ce3 100644 --- a/e2e-playwright/dashboards-suite/set-options-from-ui.spec.ts +++ b/e2e-playwright/dashboards-suite/set-options-from-ui.spec.ts @@ -5,7 +5,7 @@ const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/snapshot-create.spec.ts b/e2e-playwright/dashboards-suite/snapshot-create.spec.ts index 123aa7f3279..50febc211b8 100644 --- a/e2e-playwright/dashboards-suite/snapshot-create.spec.ts +++ b/e2e-playwright/dashboards-suite/snapshot-create.spec.ts @@ -5,7 +5,7 @@ const DASHBOARD_UID = 'ZqZnVvFZz'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', dashboardScene: false, // this test is for the old sharing modal only used when scenes is turned off }, }); diff --git a/e2e-playwright/dashboards-suite/templating-dashboard-links-and-variables.spec.ts b/e2e-playwright/dashboards-suite/templating-dashboard-links-and-variables.spec.ts index 1d8fd32ff06..1806aca24bf 100644 --- a/e2e-playwright/dashboards-suite/templating-dashboard-links-and-variables.spec.ts +++ b/e2e-playwright/dashboards-suite/templating-dashboard-links-and-variables.spec.ts @@ -5,7 +5,7 @@ const DASHBOARD_UID = 'yBCC3aKGk'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/dashboards-suite/textbox-variables.spec.ts b/e2e-playwright/dashboards-suite/textbox-variables.spec.ts index 4fb56ef8b8e..b78e781dad1 100644 --- a/e2e-playwright/dashboards-suite/textbox-variables.spec.ts +++ b/e2e-playwright/dashboards-suite/textbox-variables.spec.ts @@ -7,7 +7,7 @@ const PAGE_UNDER_TEST = 'AejrN1AMz'; test.use({ featureToggles: { kubernetesDashboards: process.env.FORCE_V2_DASHBOARDS_API === 'true', - kubernetesDashboardsV2: process.env.FORCE_V2_DASHBOARDS_API === 'true', + dashboardNewLayouts: process.env.FORCE_V2_DASHBOARDS_API === 'true', }, }); diff --git a/e2e-playwright/panels-suite/canvas-icon-mappings.spec.ts b/e2e-playwright/panels-suite/canvas-icon-mappings.spec.ts new file mode 100644 index 00000000000..72de7a6c62c --- /dev/null +++ b/e2e-playwright/panels-suite/canvas-icon-mappings.spec.ts @@ -0,0 +1,99 @@ +import { test, expect } from '@grafana/plugin-e2e'; + +const DASHBOARD_UID = 'canvas-icon-fix-test-v2'; +const PANEL_TITLE = 'Various SVG icons'; + +test.describe('Canvas Panel - Icon Mappings', () => { + test('should render field-based icons from value mappings correctly', async ({ gotoDashboardPage, page }) => { + await test.step('Navigate to dashboard and wait for panel to load', async () => { + await gotoDashboardPage({ uid: DASHBOARD_UID }); + await page.waitForSelector('svg', { timeout: 10000 }); + }); + + await test.step('Verify value mapping text values are displayed', async () => { + await expect(page.getByText('Success')).toBeVisible(); + await expect(page.getByText('Warning')).toBeVisible(); + await expect(page.getByText('Error')).toBeVisible(); + }); + + await test.step('Verify SVG icons rendered for mapped values', async () => { + const svgCount = await page.locator('svg').count(); + expect(svgCount).toBeGreaterThanOrEqual(3); + }); + }); + + test('should render fixed path icons correctly', async ({ gotoDashboardPage, page }) => { + await test.step('Set up network interception for absolute URL icon', async () => { + await page.route('https://grafana.com/static/assets/img/grafana_icon.svg', async (route) => { + const dummySvg = ` + + TEST + `; + await route.fulfill({ + status: 200, + contentType: 'image/svg+xml', + body: dummySvg, + }); + }); + }); + + await test.step('Navigate to dashboard and wait for SVGs to load', async () => { + await gotoDashboardPage({ uid: DASHBOARD_UID }); + await page.waitForSelector('svg:not([aria-hidden="true"])', { timeout: 10000 }); + await page.waitForLoadState('networkidle', { timeout: 10000 }); + }); + + await test.step('Verify at least 5 visible SVG icons are rendered (3 mapped + 2 fixed)', async () => { + const visibleSvgs = page.locator('svg:not([aria-hidden="true"])'); + const svgCount = await visibleSvgs.count(); + expect(svgCount).toBeGreaterThanOrEqual(5); + }); + + await test.step('Verify visible SVG icons have content', async () => { + const visibleSvgs = page.locator('svg:not([aria-hidden="true"])'); + const count = await visibleSvgs.count(); + + for (let i = 0; i < Math.min(count, 5); i++) { + const svg = visibleSvgs.nth(i); + await expect(svg).toBeAttached(); + const svgContent = await svg.innerHTML(); + expect(svgContent.length).toBeGreaterThan(0); + } + }); + }); + + test('should not make invalid requests for unmapped numeric values', async ({ gotoDashboardPage, page }) => { + const failedRequests: string[] = []; + + await test.step('Set up network request monitoring', async () => { + page.on('requestfailed', (request) => { + const url = request.url(); + if (url.match(/\/build\/\d+$/)) { + failedRequests.push(url); + } + }); + }); + + await test.step('Navigate to dashboard and wait for loading', async () => { + await gotoDashboardPage({ uid: DASHBOARD_UID }); + await page.waitForTimeout(2000); + }); + + await test.step('Verify no invalid numeric path requests were made', async () => { + expect(failedRequests).toHaveLength(0); + }); + }); + + test('should display text values from value mappings correctly', async ({ gotoDashboardPage, page }) => { + await test.step('Navigate to dashboard', async () => { + await gotoDashboardPage({ uid: DASHBOARD_UID }); + }); + + await test.step('Verify mapped text values are displayed', async () => { + await expect(page.getByText('Success')).toBeVisible(); + await expect(page.getByText('Warning')).toBeVisible(); + await expect(page.getByText('Error')).toBeVisible(); + await expect(page.getByText('No mapping (14)')).toBeVisible(); + }); + }); +}); diff --git a/e2e-playwright/panels-suite/canvas-scene.spec.ts b/e2e-playwright/panels-suite/canvas-scene.spec.ts index b1fc028f3ae..c0b392d544b 100644 --- a/e2e-playwright/panels-suite/canvas-scene.spec.ts +++ b/e2e-playwright/panels-suite/canvas-scene.spec.ts @@ -2,18 +2,16 @@ import { Locator } from '@playwright/test'; import { test, expect } from '@grafana/plugin-e2e'; -import { setVisualization } from './vizpicker-utils'; - test.use({ featureToggles: { canvasPanelPanZoom: true, }, }); test.describe('Canvas Panel - Scene Tests', () => { - test.beforeEach(async ({ page, gotoDashboardPage, selectors }) => { + test.beforeEach(async ({ page, gotoDashboardPage }) => { const dashboardPage = await gotoDashboardPage({}); const panelEditPage = await dashboardPage.addPanel(); - await setVisualization(panelEditPage, 'Canvas', selectors); + await panelEditPage.setVisualization('Canvas'); // Wait for canvas panel to load await page.waitForSelector('[data-testid="canvas-scene-pan-zoom"]', { timeout: 10000 }); diff --git a/e2e-playwright/panels-suite/gauge.spec.ts b/e2e-playwright/panels-suite/gauge.spec.ts new file mode 100644 index 00000000000..cb4b26e9850 --- /dev/null +++ b/e2e-playwright/panels-suite/gauge.spec.ts @@ -0,0 +1,101 @@ +import { test, expect } from '@grafana/plugin-e2e'; + +// this test requires a larger viewport so all gauge panels load properly +test.use({ + featureToggles: { newGauge: true }, + viewport: { width: 1280, height: 3000 }, +}); + +const OLD_GAUGES_DASHBOARD_UID = '_5rDmaQiz'; +const NEW_GAUGES_DASHBOARD_UID = 'panel-tests-gauge-new'; + +test.describe( + 'Gauge Panel', + { + tag: ['@panels', '@gauge'], + }, + () => { + test('successfully migrates all gauge panels', async ({ gotoDashboardPage, selectors }) => { + const dashboardPage = await gotoDashboardPage({ uid: OLD_GAUGES_DASHBOARD_UID }); + + // check that gauges are rendered + const gaugeElements = dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Visualization.Gauge.Container + ); + await expect(gaugeElements).toHaveCount(16); + + // check that no panel errors exist + const errorInfo = dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerCornerInfo('error')); + await expect(errorInfo).toBeHidden(); + }); + + test('renders new gauge panels', async ({ gotoDashboardPage, selectors }) => { + // open Panel Tests - Gauge + const dashboardPage = await gotoDashboardPage({ uid: NEW_GAUGES_DASHBOARD_UID }); + + // check that gauges are rendered + const gaugeElements = dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Visualization.Gauge.Container + ); + await expect(gaugeElements).toHaveCount(32); + + // check that no panel errors exist + const errorInfo = dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerCornerInfo('error')); + await expect(errorInfo).toBeHidden(); + }); + + test('renders sparklines in gauge panels', async ({ gotoDashboardPage, page }) => { + await gotoDashboardPage({ + uid: NEW_GAUGES_DASHBOARD_UID, + queryParams: new URLSearchParams({ editPanel: '11' }), + }); + + await expect(page.locator('.uplot')).toHaveCount(5); + }); + + test('"no data"', async ({ gotoDashboardPage, selectors }) => { + const dashboardPage = await gotoDashboardPage({ + uid: NEW_GAUGES_DASHBOARD_UID, + queryParams: new URLSearchParams({ editPanel: '36' }), + }); + + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.Panels.Visualization.Gauge.Container), + 'that the gauge does not appear' + ).toBeHidden(); + + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.PanelDataErrorMessage), + 'that the empty text appears' + ).toHaveText('No data'); + + // update the "No value" option and see if the panel updates + const noValueOption = dashboardPage + .getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldLabel('Standard options No value')) + .locator('input'); + + await noValueOption.fill('My empty value'); + await noValueOption.blur(); + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.Panels.Visualization.Gauge.Container), + 'that the empty text shows up in an empty gauge' + ).toHaveText('My empty value'); + + // test the "no numeric fields" message on the next panel + const dashboardPage2 = await gotoDashboardPage({ + uid: NEW_GAUGES_DASHBOARD_UID, + queryParams: new URLSearchParams({ editPanel: '37' }), + }); + + await expect( + dashboardPage2.getByGrafanaSelector(selectors.components.Panels.Visualization.Gauge.Container), + 'that the gauge does not appear' + ).toBeHidden(); + + await expect( + dashboardPage2.getByGrafanaSelector(selectors.components.Panels.Panel.PanelDataErrorMessage), + 'that the empty text appears' + ).toHaveText('Data is missing a number field'); + }); + } +); diff --git a/e2e-playwright/panels-suite/state-timeline.spec.ts b/e2e-playwright/panels-suite/state-timeline.spec.ts index ebdeb8d5398..d851a25f8af 100644 --- a/e2e-playwright/panels-suite/state-timeline.spec.ts +++ b/e2e-playwright/panels-suite/state-timeline.spec.ts @@ -78,6 +78,16 @@ test.describe('Panels test: StateTimeine', { tag: ['@panels', '@state-timeline'] await dashboardPage.getByGrafanaSelector(selectors.components.Portal.container).getByLabel('Close').click(); await expect(tooltip, 'tooltip closed on "x" click').toBeHidden(); + // test that CMD/CTRL+C doesn't dismiss the tooltip + await stateTimelineUplot.click({ position: { x: 100, y: 50 } }); + await expect(tooltip, 'tooltip appears on click').toBeVisible(); + await page.keyboard.press('Meta+C'); + await expect(tooltip, 'tooltip persists after CMD/CTRL+C').toBeVisible(); + + // test that Escape key dismisses the tooltip + await page.keyboard.press('Escape'); + await expect(tooltip, 'tooltip closed on Escape key').toBeHidden(); + // disable tooltips await dashboardPage .getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldLabel('Tooltip Tooltip mode')) diff --git a/e2e-playwright/panels-suite/status-history.spec.ts b/e2e-playwright/panels-suite/status-history.spec.ts index bece3aa47c7..b2e628c0795 100644 --- a/e2e-playwright/panels-suite/status-history.spec.ts +++ b/e2e-playwright/panels-suite/status-history.spec.ts @@ -76,6 +76,16 @@ test.describe('Panels test: StatusHistory', { tag: ['@panels', '@status-history' await dashboardPage.getByGrafanaSelector(selectors.components.Portal.container).getByLabel('Close').click(); await expect(tooltip, 'tooltip closed on "x" click').toBeHidden(); + // test that CMD/CTRL+C doesn't dismiss the tooltip + await statusHistoryUplot.click({ position: { x: 100, y: 50 } }); + await expect(tooltip, 'tooltip appears on click').toBeVisible(); + await page.keyboard.press('Meta+C'); + await expect(tooltip, 'tooltip persists after CMD/CTRL+C').toBeVisible(); + + // test that Escape key dismisses the tooltip + await page.keyboard.press('Escape'); + await expect(tooltip, 'tooltip closed on Escape key').toBeHidden(); + // disable tooltips await dashboardPage .getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldLabel('Tooltip Tooltip mode')) diff --git a/e2e-playwright/panels-suite/table-kitchenSink.spec.ts b/e2e-playwright/panels-suite/table-kitchenSink.spec.ts index a14085aa753..ac10cb2b735 100644 --- a/e2e-playwright/panels-suite/table-kitchenSink.spec.ts +++ b/e2e-playwright/panels-suite/table-kitchenSink.spec.ts @@ -82,9 +82,9 @@ test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table'] await expect(getCellHeight(page, 1, longTextColIdx)).resolves.toBeLessThan(100); // click cell inspect, check that cell inspection pops open in the side as we'd expect. - await loremIpsumCell.getByLabel('Inspect value').click(); const loremIpsumText = await loremIpsumCell.textContent(); expect(loremIpsumText).toBeDefined(); + await loremIpsumCell.getByLabel('Inspect value').click(); await expect(page.getByRole('dialog').getByText(loremIpsumText!)).toBeVisible(); }); @@ -343,6 +343,33 @@ test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table'] // TODO -- saving for another day. }); + test('Tests nested table expansion', async ({ gotoDashboardPage, selectors, page }) => { + const dashboardPage = await gotoDashboardPage({ + uid: DASHBOARD_UID, + queryParams: new URLSearchParams({ editPanel: '4' }), + }); + + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('Nested tables')) + ).toBeVisible(); + + await waitForTableLoad(page); + + await expect(page.locator('[role="row"]')).toHaveCount(3); // header + 2 rows + + const firstRowExpander = dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Visualization.TableNG.RowExpander) + .first(); + + await firstRowExpander.click(); + await expect(page.locator('[role="row"]')).not.toHaveCount(3); // more rows are present now, it is dynamic tho. + + // TODO: test sorting + + await firstRowExpander.click(); + await expect(page.locator('[role="row"]')).toHaveCount(3); // back to original state + }); + test('Tests tooltip interactions', async ({ gotoDashboardPage, selectors }) => { const dashboardPage = await gotoDashboardPage({ uid: DASHBOARD_UID, diff --git a/e2e-playwright/panels-suite/vizpicker-utils.ts b/e2e-playwright/panels-suite/vizpicker-utils.ts deleted file mode 100644 index 1785dd7e04a..00000000000 --- a/e2e-playwright/panels-suite/vizpicker-utils.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { expect, E2ESelectorGroups, PanelEditPage } from '@grafana/plugin-e2e'; - -// this replaces the panelEditPage.setVisualization method used previously in tests, since it -// does not know how to use the updated 12.4 viz picker UI to set the visualization -export const setVisualization = async (panelEditPage: PanelEditPage, vizName: string, selectors: E2ESelectorGroups) => { - const vizPicker = panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.toggleVizPicker); - await expect(vizPicker, '"Change" button should be visible').toBeVisible(); - await vizPicker.click(); - - const allVizTabBtn = panelEditPage.getByGrafanaSelector(selectors.components.Tab.title('All visualizations')); - await expect(allVizTabBtn, '"All visualiations" button should be visible').toBeVisible(); - await allVizTabBtn.click(); - - const vizItem = panelEditPage.getByGrafanaSelector(selectors.components.PluginVisualization.item(vizName)); - await expect(vizItem, `"${vizName}" item should be visible`).toBeVisible(); - await vizItem.scrollIntoViewIfNeeded(); - await vizItem.click(); - - await expect(vizPicker, '"Change" button should be visible again').toBeVisible(); - await expect( - panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.header), - 'Panel header should have the new viz type name' - ).toHaveText(vizName); -}; diff --git a/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelDataAssertion.spec.ts b/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelDataAssertion.spec.ts index 336dbef0a29..0133a3e3712 100644 --- a/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelDataAssertion.spec.ts +++ b/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelDataAssertion.spec.ts @@ -1,6 +1,5 @@ import { expect, test } from '@grafana/plugin-e2e'; -import { setVisualization } from '../../../panels-suite/vizpicker-utils'; import { formatExpectError } from '../errors'; import { successfulDataQuery } from '../mocks/queries'; @@ -25,10 +24,10 @@ test.describe( ).toContainText(['Field', 'Max', 'Mean', 'Last']); }); - test('table panel data assertions', async ({ panelEditPage, selectors }) => { + test('table panel data assertions', async ({ panelEditPage }) => { await panelEditPage.mockQueryDataResponse(successfulDataQuery, 200); await panelEditPage.datasource.set('gdev-testdata'); - await setVisualization(panelEditPage, 'Table', selectors); + await panelEditPage.setVisualization('Table'); await panelEditPage.refreshPanel(); await expect( panelEditPage.panel.locator, @@ -44,10 +43,10 @@ test.describe( ).toContainText(['val1', 'val2', 'val3', 'val4']); }); - test('timeseries panel - table view assertions', async ({ panelEditPage, selectors }) => { + test('timeseries panel - table view assertions', async ({ panelEditPage }) => { await panelEditPage.mockQueryDataResponse(successfulDataQuery, 200); await panelEditPage.datasource.set('gdev-testdata'); - await setVisualization(panelEditPage, 'Time series', selectors); + await panelEditPage.setVisualization('Time series'); await panelEditPage.refreshPanel(); await panelEditPage.toggleTableView(); await expect( diff --git a/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelEditPage.spec.ts b/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelEditPage.spec.ts index 93e0525ab0e..46c36277848 100644 --- a/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelEditPage.spec.ts +++ b/e2e-playwright/plugin-e2e/plugin-e2e-api-tests/as-admin-user/panelEditPage.spec.ts @@ -1,6 +1,5 @@ import { expect, test } from '@grafana/plugin-e2e'; -import { setVisualization } from '../../../panels-suite/vizpicker-utils'; import { formatExpectError } from '../errors'; import { successfulDataQuery } from '../mocks/queries'; import { scenarios } from '../mocks/resources'; @@ -54,10 +53,10 @@ test.describe( ).toHaveText(scenarios.map((s) => s.name)); }); - test('mocked query data response', async ({ panelEditPage, page, selectors }) => { + test('mocked query data response', async ({ panelEditPage, page }) => { await panelEditPage.mockQueryDataResponse(successfulDataQuery, 200); await panelEditPage.datasource.set('gdev-testdata'); - await setVisualization(panelEditPage, TABLE_VIZ_NAME, selectors); + await panelEditPage.setVisualization(TABLE_VIZ_NAME); await panelEditPage.refreshPanel(); await expect( panelEditPage.panel.getErrorIcon(), @@ -76,7 +75,7 @@ test.describe( selectors, page, }) => { - await setVisualization(panelEditPage, TABLE_VIZ_NAME, selectors); + await panelEditPage.setVisualization(TABLE_VIZ_NAME); await expect( panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.header), formatExpectError('Expected panel visualization to be set to table') @@ -93,8 +92,8 @@ test.describe( ).toBeVisible(); }); - test('Select time zone in timezone picker', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('Select time zone in timezone picker', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const axisOptions = await panelEditPage.getCustomOptions('Axis'); const timeZonePicker = axisOptions.getSelect('Time zone'); @@ -102,8 +101,8 @@ test.describe( await expect(timeZonePicker).toHaveSelected('Europe/Stockholm'); }); - test('select unit in unit picker', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('select unit in unit picker', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const standardOptions = panelEditPage.getStandardOptions(); const unitPicker = standardOptions.getUnitPicker('Unit'); @@ -112,8 +111,8 @@ test.describe( await expect(unitPicker).toHaveSelected('Pixels'); }); - test('enter value in number input', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('enter value in number input', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const axisOptions = panelEditPage.getCustomOptions('Axis'); const lineWith = axisOptions.getNumberInput('Soft min'); @@ -122,8 +121,8 @@ test.describe( await expect(lineWith).toHaveValue('10'); }); - test('enter value in slider', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('enter value in slider', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const graphOptions = panelEditPage.getCustomOptions('Graph styles'); const lineWidth = graphOptions.getSliderInput('Line width'); @@ -132,8 +131,8 @@ test.describe( await expect(lineWidth).toHaveValue('10'); }); - test('select value in single value select', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('select value in single value select', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const standardOptions = panelEditPage.getStandardOptions(); const colorSchemeSelect = standardOptions.getSelect('Color scheme'); @@ -141,8 +140,8 @@ test.describe( await expect(colorSchemeSelect).toHaveSelected('Classic palette'); }); - test('clear input', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('clear input', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const panelOptions = panelEditPage.getPanelOptions(); const title = panelOptions.getTextInput('Title'); @@ -151,8 +150,8 @@ test.describe( await expect(title).toHaveValue(''); }); - test('enter value in input', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('enter value in input', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const panelOptions = panelEditPage.getPanelOptions(); const description = panelOptions.getTextInput('Description'); @@ -161,8 +160,8 @@ test.describe( await expect(description).toHaveValue('This is a panel'); }); - test('unchecking switch', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('unchecking switch', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const axisOptions = panelEditPage.getCustomOptions('Axis'); const showBorder = axisOptions.getSwitch('Show border'); @@ -174,8 +173,8 @@ test.describe( await expect(showBorder).toBeChecked({ checked: false }); }); - test('checking switch', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('checking switch', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const axisOptions = panelEditPage.getCustomOptions('Axis'); const showBorder = axisOptions.getSwitch('Show border'); @@ -184,8 +183,8 @@ test.describe( await expect(showBorder).toBeChecked(); }); - test('re-selecting value in radio button group', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('re-selecting value in radio button group', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const axisOptions = panelEditPage.getCustomOptions('Axis'); const placement = axisOptions.getRadioGroup('Placement'); @@ -196,8 +195,8 @@ test.describe( await expect(placement).toHaveChecked('Auto'); }); - test('selecting value in radio button group', async ({ panelEditPage, selectors }) => { - await setVisualization(panelEditPage, TIME_SERIES_VIZ_NAME, selectors); + test('selecting value in radio button group', async ({ panelEditPage }) => { + await panelEditPage.setVisualization(TIME_SERIES_VIZ_NAME); const axisOptions = panelEditPage.getCustomOptions('Axis'); const placement = axisOptions.getRadioGroup('Placement'); diff --git a/e2e-playwright/smoke-tests-suite/panels.spec.ts b/e2e-playwright/smoke-tests-suite/panels.spec.ts index 22f6088d99d..0ad50a1aed7 100644 --- a/e2e-playwright/smoke-tests-suite/panels.spec.ts +++ b/e2e-playwright/smoke-tests-suite/panels.spec.ts @@ -1,4 +1,4 @@ -import { BootData } from '@grafana/data'; +import { BootData, PanelPluginMeta } from '@grafana/data'; import { test, expect } from '@grafana/plugin-e2e'; test.describe( @@ -22,7 +22,7 @@ test.describe( await dashboardPage.addPanel(); // Get panel types from window object - const panelTypes = await page.evaluate(() => { + const panelTypes: PanelPluginMeta[] = await page.evaluate(() => { // @grafana/plugin-e2e doesn't export the full bootdata config // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const win = window as typeof window & { grafanaBootData: BootData }; diff --git a/e2e-playwright/utils/scope-helpers.ts b/e2e-playwright/utils/scope-helpers.ts index 749577ecb05..fc88a79d8fa 100644 --- a/e2e-playwright/utils/scope-helpers.ts +++ b/e2e-playwright/utils/scope-helpers.ts @@ -156,13 +156,18 @@ export async function applyScopes(page: Page, scopes?: TestScope[]) { return; } - const url: string = + const dashboardBindingsUrl: string = '**/apis/scope.grafana.app/v0alpha1/namespaces/*/find/scope_dashboard_bindings?' + scopes.map((scope) => `scope=scope-${scope.name}`).join('&'); + const scopeNavigationsUrl: string = + '**/apis/scope.grafana.app/v0alpha1/namespaces/*/find/scope_navigations?' + + scopes.map((scope) => `scope=scope-${scope.name}`).join('&'); + const groups: string[] = ['Most relevant', 'Dashboards', 'Something else', '']; - await page.route(url, async (route) => { + // Mock scope_dashboard_bindings endpoint + await page.route(dashboardBindingsUrl, async (route) => { await route.fulfill({ status: 200, contentType: 'application/json', @@ -215,7 +220,52 @@ export async function applyScopes(page: Page, scopes?: TestScope[]) { }); }); - const responsePromise = page.waitForResponse((response) => response.url().includes(`/find/scope_dashboard_bindings`)); + // Mock scope_navigations endpoint + await page.route(scopeNavigationsUrl, async (route) => { + await route.fulfill({ + status: 200, + contentType: 'application/json', + body: JSON.stringify({ + apiVersion: 'scope.grafana.app/v0alpha1', + items: scopes.flatMap((scope) => { + const navigations: Array<{ + kind: string; + apiVersion: string; + metadata: { name: string; resourceVersion: string; creationTimestamp: string }; + spec: { url: string; scope: string }; + status: { title: string }; + }> = []; + + // Create a scope navigation if dashboardUid is provided + if (scope.dashboardUid && scope.addLinks) { + navigations.push({ + kind: 'ScopeNavigation', + apiVersion: 'scope.grafana.app/v0alpha1', + metadata: { + name: `scope-${scope.name}-nav`, + resourceVersion: '1', + creationTimestamp: 'stamp', + }, + spec: { + url: `/d/${scope.dashboardUid}`, + scope: `scope-${scope.name}`, + }, + status: { + title: scope.dashboardTitle ?? scope.title, + }, + }); + } + + return navigations; + }), + }), + }); + }); + + const responsePromise = page.waitForResponse( + (response) => + response.url().includes(`/find/scope_dashboard_bindings`) || response.url().includes(`/find/scope_navigations`) + ); const scopeRequestPromises: Array> = []; for (const scope of scopes) { diff --git a/e2e-playwright/utils/scopes.ts b/e2e-playwright/utils/scopes.ts index c5b141d4eb7..73a29a5da95 100644 --- a/e2e-playwright/utils/scopes.ts +++ b/e2e-playwright/utils/scopes.ts @@ -124,5 +124,23 @@ export const testScopesWithRedirect = (): TestScope[] => { dashboardTitle: 'CUJ Dashboard 2', addLinks: true, }, + { + name: 'sn-redirect-setup', + title: 'Setup Navigation', + // No redirectPath - used to set up scope navigation to dashboard-1 + filters: [{ key: 'namespace', operator: 'equals', value: 'setup-nav' }], + dashboardUid: 'cuj-dashboard-1', // Creates scope navigation to this dashboard + dashboardTitle: 'CUJ Dashboard 1', + addLinks: true, + }, + { + name: 'sn-redirect-with-navigation', + title: 'Redirect With Navigation', + redirectPath: '/d/cuj-dashboard-3', // Redirect target + filters: [{ key: 'namespace', operator: 'equals', value: 'redirect-with-nav' }], + dashboardUid: 'cuj-dashboard-1', // Creates scope navigation to this dashboard + dashboardTitle: 'CUJ Dashboard 1', + addLinks: true, + }, ]; }; diff --git a/e2e-playwright/various-suite/gauge.spec.ts b/e2e-playwright/various-suite/gauge.spec.ts deleted file mode 100644 index 3e2d6023c95..00000000000 --- a/e2e-playwright/various-suite/gauge.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { test, expect } from '@grafana/plugin-e2e'; - -// this test requires a larger viewport so all gauge panels load properly -test.use({ - viewport: { width: 1280, height: 1080 }, -}); - -test.describe( - 'Gauge Panel', - { - tag: ['@various'], - }, - () => { - test('Gauge rendering e2e tests', async ({ gotoDashboardPage, selectors, page }) => { - // open Panel Tests - Gauge - const dashboardPage = await gotoDashboardPage({ uid: '_5rDmaQiz' }); - - // check that gauges are rendered - const gaugeElements = page.locator('.flot-base'); - await expect(gaugeElements).toHaveCount(16); - - // check that no panel errors exist - const errorInfo = dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerCornerInfo('error')); - await expect(errorInfo).toBeHidden(); - }); - } -); diff --git a/e2e-playwright/various-suite/prometheus-variable-editor.spec.ts b/e2e-playwright/various-suite/prometheus-variable-editor.spec.ts index 16a722854aa..82b293da581 100644 --- a/e2e-playwright/various-suite/prometheus-variable-editor.spec.ts +++ b/e2e-playwright/various-suite/prometheus-variable-editor.spec.ts @@ -95,7 +95,7 @@ test.describe( await createNewPanelButton.click(); // Close the data source picker modal - const closeButton = page.getByRole('button', { name: 'Close menu' }); + const closeButton = page.getByRole('button', { name: 'Close', exact: true }); await closeButton.click({ force: true }); // Select prom data source from the data source list diff --git a/e2e-playwright/various-suite/visualization-suggestions-v2.spec.ts b/e2e-playwright/various-suite/visualization-suggestions-v2.spec.ts new file mode 100644 index 00000000000..282ec1314cc --- /dev/null +++ b/e2e-playwright/various-suite/visualization-suggestions-v2.spec.ts @@ -0,0 +1,178 @@ +import { test, expect } from '@grafana/plugin-e2e'; + +test.use({ + featureToggles: { + newVizSuggestions: true, + externalVizSuggestions: false, + }, + viewport: { + width: 800, + height: 1500, + }, +}); + +test.describe( + 'Visualization suggestions v2', + { + tag: ['@various', '@suggestions'], + }, + () => { + test('Should be shown and clickable', async ({ selectors, gotoPanelEditPage }) => { + // Open dashboard with edit panel + const panelEditPage = await gotoPanelEditPage({ + dashboard: { + uid: 'aBXrJ0R7z', + }, + id: '9', + }); + + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.Panels.Panel.content).locator('.uplot'), + 'time series to be rendered inside panel' + ).toBeVisible(); + + // Try visualization suggestions + await panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.toggleVizPicker).click(); + await panelEditPage.getByGrafanaSelector(selectors.components.Tab.title('Suggestions')).click(); + + // Verify we see suggestions + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.VisualizationPreview.card('Line chart')), + 'line chart suggestion to be rendered' + ).toBeVisible(); + + // TODO: in this part of the test, we will change the query and the transforms and observe suggestions being updated. + + // Select a visualization and verify table header is visible from preview + await panelEditPage.getByGrafanaSelector(selectors.components.VisualizationPreview.card('Table')).click(); + await expect( + panelEditPage + .getByGrafanaSelector(selectors.components.Panels.Panel.content) + .getByRole('grid') + .getByRole('row') + .first(), + 'table to be rendered inside panel' + ).toBeVisible(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.discardChangesButton), + 'discard changes button disabled since panel has not yet changed' + ).toBeDisabled(); + + // apply the suggestion and verify panel options are visible + await panelEditPage.getByGrafanaSelector(selectors.components.VisualizationPreview.confirm('Table')).click(); + await expect( + panelEditPage + .getByGrafanaSelector(selectors.components.Panels.Panel.content) + .getByRole('grid') + .getByRole('row') + .first(), + 'table to be rendered inside panel' + ).toBeVisible(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.header), + 'options pane to be rendered' + ).toBeVisible(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.discardChangesButton), + 'discard changes button enabled now that panel is dirty' + ).toBeEnabled(); + }); + + test('should not apply suggestion if you navigate toggle the viz picker back off', async ({ + selectors, + gotoPanelEditPage, + }) => { + // Open dashboard with edit panel + const panelEditPage = await gotoPanelEditPage({ + dashboard: { + uid: 'aBXrJ0R7z', + }, + id: '9', + }); + + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.Panels.Panel.content).locator('.uplot'), + 'time series to be rendered inside panel;' + ).toBeVisible(); + + // Try visualization suggestions + await panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.toggleVizPicker).click(); + await panelEditPage.getByGrafanaSelector(selectors.components.Tab.title('Suggestions')).click(); + + // Verify we see suggestions + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.VisualizationPreview.card('Line chart')), + 'line chart suggestion to be rendered' + ).toBeVisible(); + + // Select a visualization + await panelEditPage.getByGrafanaSelector(selectors.components.VisualizationPreview.card('Table')).click(); + await expect( + panelEditPage + .getByGrafanaSelector(selectors.components.Panels.Panel.content) + .getByRole('grid') + .getByRole('row') + .first(), + 'table to be rendered inside panel' + ).toBeVisible(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.discardChangesButton) + ).toBeDisabled(); + + // Verify that toggling the viz picker back cancels the suggestion, restores the line chart, shows panel options + await panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.toggleVizPicker).click(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.Panels.Panel.content).locator('.uplot'), + 'time series to be rendered inside panel' + ).toBeVisible(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.header), + 'options pane to be rendered' + ).toBeVisible(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.discardChangesButton), + 'discard changes button is still disabled since no changes were applied' + ).toBeDisabled(); + }); + + test('should not apply suggestion if you navigate back to the dashboard', async ({ + page, + selectors, + gotoPanelEditPage, + }) => { + // Open dashboard with edit panel + const panelEditPage = await gotoPanelEditPage({ + dashboard: { + uid: 'aBXrJ0R7z', + }, + id: '9', + }); + + // Try visualization suggestions + await panelEditPage.getByGrafanaSelector(selectors.components.PanelEditor.toggleVizPicker).click(); + await panelEditPage.getByGrafanaSelector(selectors.components.Tab.title('Suggestions')).click(); + + // Verify we see suggestions + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.VisualizationPreview.card('Line chart')), + 'line chart suggestion to be rendered' + ).toBeVisible(); + + // Select a visualization + await panelEditPage.getByGrafanaSelector(selectors.components.VisualizationPreview.card('Table')).click(); + await expect(page.getByRole('grid').getByRole('row').first(), 'table row to be rendered').toBeVisible(); + await expect( + panelEditPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.discardChangesButton) + ).toBeDisabled(); + + // Verify that navigating back to the dashboard cancels the suggestion and restores the line chart. + await panelEditPage + .getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton) + .click(); + await expect( + page.locator('[data-viz-panel-key="panel-9"]').locator('.uplot'), + 'time series to be rendered inside the panel' + ).toBeVisible(); + }); + } +); diff --git a/e2e-playwright/various-suite/visualization-suggestions.spec.ts b/e2e-playwright/various-suite/visualization-suggestions.spec.ts index d01447b7eb7..7872e5a69d0 100644 --- a/e2e-playwright/various-suite/visualization-suggestions.spec.ts +++ b/e2e-playwright/various-suite/visualization-suggestions.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e'; test.describe( 'Visualization suggestions', { - tag: ['@various'], + tag: ['@various', '@suggestions'], }, () => { test('Should be shown and clickable', async ({ page, selectors, gotoPanelEditPage }) => { diff --git a/e2e/cypress/plugins/typescriptPreprocessor.js b/e2e/cypress/plugins/typescriptPreprocessor.js index 27765380994..ed054f6f943 100644 --- a/e2e/cypress/plugins/typescriptPreprocessor.js +++ b/e2e/cypress/plugins/typescriptPreprocessor.js @@ -18,6 +18,7 @@ const webpackOptions = { }, resolve: { extensions: ['.ts', '.js'], + conditionNames: ['@grafana-app/source', '...'], }, }; diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 9ecdfaed054..250dbd20348 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -397,7 +397,7 @@ }, "packages/grafana-prometheus/src/language_provider.ts": { "@typescript-eslint/no-explicit-any": { - "count": 7 + "count": 2 } }, "packages/grafana-prometheus/src/language_utils.ts": { @@ -669,7 +669,7 @@ }, "packages/grafana-ui/src/components/InteractiveTable/InteractiveTable.story.tsx": { "no-restricted-syntax": { - "count": 3 + "count": 2 } }, "packages/grafana-ui/src/components/JSONFormatter/json_explorer/json_explorer.ts": { @@ -763,11 +763,6 @@ "count": 1 } }, - "packages/grafana-ui/src/components/Select/resetSelectStyles.ts": { - "@typescript-eslint/no-explicit-any": { - "count": 1 - } - }, "packages/grafana-ui/src/components/Select/types.ts": { "@typescript-eslint/no-explicit-any": { "count": 6 @@ -786,11 +781,6 @@ "count": 13 } }, - "packages/grafana-ui/src/components/Sparkline/Sparkline.tsx": { - "react-prefer-function-component/react-prefer-function-component": { - "count": 1 - } - }, "packages/grafana-ui/src/components/Table/Cells/TableCell.tsx": { "@typescript-eslint/consistent-type-assertions": { "count": 3 @@ -809,11 +799,6 @@ "count": 2 } }, - "packages/grafana-ui/src/components/Table/TableNG/utils.ts": { - "@typescript-eslint/consistent-type-assertions": { - "count": 1 - } - }, "packages/grafana-ui/src/components/Table/TableRT/Filter.tsx": { "@typescript-eslint/no-explicit-any": { "count": 1 @@ -886,11 +871,6 @@ "count": 1 } }, - "packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx": { - "no-restricted-syntax": { - "count": 1 - } - }, "packages/grafana-ui/src/components/VizLegend/types.ts": { "@typescript-eslint/no-explicit-any": { "count": 2 @@ -1041,11 +1021,6 @@ "count": 2 } }, - "public/app/core/actions/index.ts": { - "no-barrel-files/no-barrel-files": { - "count": 4 - } - }, "public/app/core/components/AccessControl/PermissionList.tsx": { "no-restricted-syntax": { "count": 1 @@ -1447,22 +1422,6 @@ "count": 1 } }, - "public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx": { - "@typescript-eslint/consistent-type-assertions": { - "count": 1 - }, - "@typescript-eslint/no-explicit-any": { - "count": 2 - }, - "no-restricted-syntax": { - "count": 1 - } - }, - "public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx": { - "no-restricted-syntax": { - "count": 1 - } - }, "public/app/features/alerting/unified/components/receivers/form/CloudCommonChannelSettings.tsx": { "no-restricted-syntax": { "count": 1 @@ -1473,17 +1432,6 @@ "count": 1 } }, - "public/app/features/alerting/unified/components/receivers/form/ReceiverForm.tsx": { - "@typescript-eslint/consistent-type-assertions": { - "count": 2 - }, - "@typescript-eslint/no-explicit-any": { - "count": 1 - }, - "no-restricted-syntax": { - "count": 1 - } - }, "public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx": { "@typescript-eslint/consistent-type-assertions": { "count": 1 @@ -1832,7 +1780,7 @@ }, "public/app/features/dashboard-scene/edit-pane/DashboardEditPaneSplitter.tsx": { "react-hooks/rules-of-hooks": { - "count": 4 + "count": 5 } }, "public/app/features/dashboard-scene/inspect/HelpWizard/HelpWizard.tsx": { @@ -1845,11 +1793,6 @@ "count": 1 } }, - "public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx": { - "no-restricted-syntax": { - "count": 1 - } - }, "public/app/features/dashboard-scene/pages/DashboardScenePage.tsx": { "@typescript-eslint/consistent-type-assertions": { "count": 2 @@ -1940,11 +1883,6 @@ "count": 1 } }, - "public/app/features/dashboard-scene/serialization/angularMigration.test.ts": { - "@typescript-eslint/no-explicit-any": { - "count": 1 - } - }, "public/app/features/dashboard-scene/serialization/buildNewDashboardSaveModel.ts": { "@typescript-eslint/consistent-type-assertions": { "count": 1 @@ -1968,11 +1906,6 @@ "count": 1 } }, - "public/app/features/dashboard-scene/settings/JsonModelEditView.tsx": { - "react/no-unescaped-entities": { - "count": 2 - } - }, "public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx": { "react-hooks/rules-of-hooks": { "count": 4 @@ -2001,11 +1934,6 @@ "count": 1 } }, - "public/app/features/dashboard-scene/settings/variables/components/VariableTextAreaField.tsx": { - "no-restricted-syntax": { - "count": 1 - } - }, "public/app/features/dashboard-scene/settings/variables/components/VariableTextField.tsx": { "no-restricted-syntax": { "count": 1 @@ -2062,9 +1990,6 @@ }, "@typescript-eslint/no-explicit-any": { "count": 3 - }, - "no-restricted-syntax": { - "count": 3 } }, "public/app/features/dashboard-scene/v2schema/ImportDashboardOverviewV2.tsx": { @@ -2457,11 +2382,6 @@ "count": 1 } }, - "public/app/features/datasources/components/DataSourceLoadError.tsx": { - "no-restricted-syntax": { - "count": 1 - } - }, "public/app/features/datasources/components/DataSourcePluginState.tsx": { "no-restricted-syntax": { "count": 3 @@ -2685,11 +2605,6 @@ "count": 2 } }, - "public/app/features/explore/hooks/useStateSync/index.ts": { - "no-barrel-files/no-barrel-files": { - "count": 1 - } - }, "public/app/features/explore/spec/helper/setup.tsx": { "@typescript-eslint/no-explicit-any": { "count": 1 @@ -2900,11 +2815,6 @@ "count": 1 } }, - "public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx": { - "@grafana/no-aria-label-selectors": { - "count": 1 - } - }, "public/app/features/panel/panellinks/linkSuppliers.ts": { "@typescript-eslint/no-explicit-any": { "count": 1 @@ -2943,11 +2853,6 @@ "count": 1 } }, - "public/app/features/plugins/admin/components/PluginDetailsPage.tsx": { - "@typescript-eslint/consistent-type-assertions": { - "count": 1 - } - }, "public/app/features/plugins/admin/helpers.ts": { "no-restricted-syntax": { "count": 2 @@ -3145,11 +3050,6 @@ "count": 2 } }, - "public/app/features/teams/TeamGroupSync.tsx": { - "react-prefer-function-component/react-prefer-function-component": { - "count": 1 - } - }, "public/app/features/templating/fieldAccessorCache.ts": { "@typescript-eslint/no-explicit-any": { "count": 1 @@ -4120,11 +4020,6 @@ "count": 1 } }, - "public/app/plugins/datasource/parca/webpack.config.ts": { - "no-barrel-files/no-barrel-files": { - "count": 1 - } - }, "public/app/plugins/datasource/prometheus/configuration/AzureAuthSettings.tsx": { "no-restricted-syntax": { "count": 1 @@ -4193,7 +4088,7 @@ "count": 1 }, "@typescript-eslint/no-explicit-any": { - "count": 2 + "count": 1 } }, "public/app/plugins/datasource/tempo/resultTransformer.ts": { @@ -4326,9 +4221,6 @@ } }, "public/app/plugins/panel/geomap/components/DebugOverlay.tsx": { - "@grafana/no-aria-label-selectors": { - "count": 1 - }, "react-prefer-function-component/react-prefer-function-component": { "count": 1 } @@ -4422,7 +4314,7 @@ }, "public/app/plugins/panel/heatmap/utils.ts": { "@typescript-eslint/consistent-type-assertions": { - "count": 16 + "count": 14 } }, "public/app/plugins/panel/histogram/Histogram.tsx": { diff --git a/eslint.config.js b/eslint.config.js index bd1be26465a..5e44ffebaf4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -585,6 +585,8 @@ module.exports = [ // FIXME: Remove once all enterprise issues are fixed - // we don't have a suppressions file/approach for enterprise code yet ...enterpriseIgnores, + // Ignore decoupled plugin webpack configs + 'public/app/**/webpack.config.ts', ], rules: { 'no-barrel-files/no-barrel-files': 'error', diff --git a/go.mod b/go.mod index e589e5a18a5..102310173d3 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( buf.build/gen/go/parca-dev/parca/protocolbuffers/go v1.36.2-20250703125925-3f0fcf4bff96.1 // @grafana/observability-traces-and-profiling cloud.google.com/go/kms v1.22.0 // @grafana/grafana-backend-group cloud.google.com/go/storage v1.55.0 // @grafana/grafana-backend-group - connectrpc.com/connect v1.18.1 // @grafana/observability-traces-and-profiling + connectrpc.com/connect v1.19.1 // @grafana/observability-traces-and-profiling cuelang.org/go v0.11.1 // @grafana/grafana-as-code dario.cat/mergo v1.0.2 // @grafana/grafana-app-platform-squad filippo.io/age v1.2.1 // @grafana/identity-access-team @@ -25,20 +25,22 @@ require ( github.com/Masterminds/semver v1.5.0 // @grafana/grafana-backend-group github.com/Masterminds/semver/v3 v3.4.0 // @grafana/grafana-developer-enablement-squad github.com/Masterminds/sprig/v3 v3.3.0 // @grafana/grafana-backend-group - github.com/ProtonMail/go-crypto v1.1.6 // @grafana/plugins-platform-backend github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f // @grafana/grafana-backend-group github.com/alicebob/miniredis/v2 v2.34.0 // @grafana/alerting-backend github.com/andybalholm/brotli v1.2.0 // @grafana/partner-datasources github.com/apache/arrow-go/v18 v18.4.1 // @grafana/plugins-platform-backend github.com/armon/go-radix v1.0.0 // @grafana/grafana-app-platform-squad github.com/aws/aws-sdk-go v1.55.7 // @grafana/aws-datasources - github.com/aws/aws-sdk-go-v2 v1.39.1 // @grafana/aws-datasources + github.com/aws/aws-sdk-go-v2 v1.40.0 // @grafana/aws-datasources + github.com/aws/aws-sdk-go-v2/credentials v1.18.21 // @grafana/grafana-operator-experience-squad github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.45.3 // @grafana/aws-datasources github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.51.0 // @grafana/aws-datasources github.com/aws/aws-sdk-go-v2/service/ec2 v1.225.2 // @grafana/aws-datasources github.com/aws/aws-sdk-go-v2/service/oam v1.18.3 // @grafana/aws-datasources github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.26.6 // @grafana/aws-datasources - github.com/aws/smithy-go v1.23.1 // @grafana/aws-datasources + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1 // @grafana/grafana-operator-experience-squad + github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 // @grafana/grafana-operator-experience-squad + github.com/aws/smithy-go v1.23.2 // @grafana/aws-datasources github.com/beevik/etree v1.4.1 // @grafana/grafana-backend-group github.com/benbjohnson/clock v1.3.5 // @grafana/alerting-backend github.com/blang/semver/v4 v4.0.0 // indirect; @grafana/grafana-developer-enablement-squad @@ -46,9 +48,9 @@ require ( github.com/blevesearch/bleve_index_api v1.2.7 // @grafana/grafana-search-and-storage github.com/blugelabs/bluge v0.2.2 // @grafana/grafana-backend-group github.com/blugelabs/bluge_segment_api v0.2.0 // @grafana/grafana-backend-group - github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // @grafana/grafana-backend-group + github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf // @grafana/grafana-backend-group github.com/bwmarrin/snowflake v0.3.0 // @grafana/grafana-app-platform-squad - github.com/centrifugal/centrifuge v0.37.2 // @grafana/grafana-app-platform-squad + github.com/centrifugal/centrifuge v0.38.0 // @grafana/grafana-app-platform-squad github.com/crewjam/saml v0.4.14 // @grafana/identity-access-team github.com/dgraph-io/badger/v4 v4.7.0 // @grafana/grafana-search-and-storage github.com/dlmiddlecote/sqlstats v1.0.2 // @grafana/grafana-backend-group @@ -87,7 +89,7 @@ require ( github.com/googleapis/gax-go/v2 v2.15.0 // @grafana/grafana-backend-group github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // @grafana/grafana-app-platform-squad - github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba // @grafana/alerting-backend + github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f // @grafana/alerting-backend github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // @grafana/identity-access-team github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 // @grafana/identity-access-team github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics @@ -97,9 +99,9 @@ require ( github.com/grafana/gofpdf v0.0.0-20250307124105-3b9c5d35577f // @grafana/sharing-squad github.com/grafana/gomemcache v0.0.0-20250318131618-74242eea118d // @grafana/grafana-operator-experience-squad github.com/grafana/grafana-api-golang-client v0.27.0 // @grafana/alerting-backend - github.com/grafana/grafana-app-sdk v0.48.5 // @grafana/grafana-app-platform-squad - github.com/grafana/grafana-app-sdk/logging v0.48.3 // @grafana/grafana-app-platform-squad - github.com/grafana/grafana-aws-sdk v1.3.0 // @grafana/aws-datasources + github.com/grafana/grafana-app-sdk v0.48.7 // @grafana/grafana-app-platform-squad + github.com/grafana/grafana-app-sdk/logging v0.48.7 // @grafana/grafana-app-platform-squad + github.com/grafana/grafana-aws-sdk v1.4.2 // @grafana/aws-datasources github.com/grafana/grafana-azure-sdk-go/v2 v2.3.1 // @grafana/partner-datasources github.com/grafana/grafana-cloud-migration-snapshot v1.9.0 // @grafana/grafana-operator-experience-squad github.com/grafana/grafana-google-sdk-go v0.4.2 // @grafana/partner-datasources @@ -110,15 +112,14 @@ require ( github.com/grafana/nanogit v0.3.0 // indirect; @grafana/grafana-git-ui-sync-team github.com/grafana/otel-profiling-go v0.5.1 // @grafana/grafana-backend-group github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // @grafana/observability-traces-and-profiling - github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae // @grafana/observability-traces-and-profiling + github.com/grafana/pyroscope/api v1.2.1-0.20251118081820-ace37f973a0f // @grafana/observability-traces-and-profiling github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // @grafana/grafana-search-and-storage github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // @grafana/plugins-platform-backend github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // @grafana/grafana-backend-group github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // @grafana/identity-access-team github.com/hashicorp/go-hclog v1.6.3 // @grafana/plugins-platform-backend github.com/hashicorp/go-multierror v1.1.1 // @grafana/alerting-squad - github.com/hashicorp/go-plugin v1.7.0 // @grafana/plugins-platform-backend - github.com/hashicorp/go-secure-stdlib/plugincontainer v0.4.2 // @grafana/plugins-platform-backend + github.com/hashicorp/go-plugin v1.7.0 // indirect; @grafana/plugins-platform-backend github.com/hashicorp/go-version v1.7.0 // @grafana/grafana-backend-group github.com/hashicorp/golang-lru/v2 v2.0.7 // @grafana/alerting-backend github.com/hashicorp/hcl/v2 v2.24.0 // @grafana/alerting-backend @@ -146,6 +147,7 @@ require ( github.com/olekukonko/tablewriter v0.0.5 // @grafana/grafana-backend-group github.com/open-feature/go-sdk v1.16.0 // @grafana/grafana-backend-group github.com/open-feature/go-sdk-contrib/providers/go-feature-flag v0.2.6 // @grafana/grafana-backend-group + github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.6 // @grafana/grafana-backend-group github.com/openfga/api/proto v0.0.0-20250909172242-b4b2a12f5c67 // @grafana/identity-access-team github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20251027165255-0f8f255e5f6c // @grafana/identity-access-team github.com/openfga/openfga v1.11.1 // @grafana/identity-access-team @@ -154,10 +156,11 @@ require ( github.com/openzipkin/zipkin-go v0.4.3 // @grafana/oss-big-tent github.com/patrickmn/go-cache v2.1.0+incompatible // @grafana/alerting-backend github.com/phpdave11/gofpdi v1.0.14 // @grafana/sharing-squad + github.com/pressly/goose/v3 v3.26.0 // @grafana/identity-access-team github.com/prometheus/alertmanager v0.28.2 // @grafana/alerting-backend github.com/prometheus/client_golang v1.23.2 // @grafana/alerting-backend github.com/prometheus/client_model v0.6.2 // @grafana/grafana-backend-group - github.com/prometheus/common v0.67.3 // @grafana/alerting-backend + github.com/prometheus/common v0.67.4 // @grafana/alerting-backend github.com/prometheus/prometheus v0.303.1 // @grafana/alerting-backend github.com/prometheus/sigv4 v0.1.2 // @grafana/alerting-backend github.com/puzpuzpuz/xsync/v4 v4.2.0 // @grafana/grafana-backend-group @@ -166,7 +169,7 @@ require ( github.com/rs/cors v1.11.1 // @grafana/identity-access-team github.com/russellhaering/goxmldsig v1.4.0 // @grafana/grafana-backend-group github.com/shopspring/decimal v1.4.0 // @grafana/grafana-datasources-core-services - github.com/spf13/cobra v1.10.1 // @grafana/grafana-app-platform-squad + github.com/spf13/cobra v1.10.2 // @grafana/grafana-app-platform-squad github.com/spf13/pflag v1.0.10 // @grafana-app-platform-squad github.com/spyzhov/ajson v0.9.6 // @grafana/grafana-sharing-squad github.com/stretchr/testify v1.11.1 // @grafana/grafana-backend-group @@ -181,18 +184,19 @@ require ( github.com/xlab/treeprint v1.2.0 // @grafana/observability-traces-and-profiling github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // @grafana/grafana-operator-experience-squad github.com/yudai/gojsondiff v1.0.0 // @grafana/grafana-backend-group + go.etcd.io/bbolt v1.4.2 // @grafana/grafana-search-and-storage go.opentelemetry.io/collector/pdata v1.44.0 // @grafana/grafana-backend-group - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // @grafana/plugins-platform-backend + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // @grafana/plugins-platform-backend go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 // @grafana/grafana-operator-experience-squad - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // @grafana/sharing-squad + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // @grafana/sharing-squad go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 // @grafana/grafana-backend-group go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel v1.38.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel v1.39.0 // @grafana/grafana-backend-group go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/sdk v1.38.0 // @grafana/grafana-backend-group - go.opentelemetry.io/otel/trace v1.38.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/sdk v1.39.0 // @grafana/grafana-backend-group + go.opentelemetry.io/otel/trace v1.39.0 // @grafana/grafana-backend-group go.uber.org/atomic v1.11.0 // @grafana/alerting-backend go.uber.org/goleak v1.3.0 // @grafana/grafana-search-and-storage go.uber.org/mock v0.6.0 // @grafana/grafana-operator-experience-squad @@ -200,30 +204,30 @@ require ( go.yaml.in/yaml/v3 v3.0.4 // @grafana/alerting-backend gocloud.dev v0.43.0 // @grafana/grafana-app-platform-squad gocloud.dev/secrets/hashivault v0.43.0 // @grafana/grafana-operator-experience-squad - golang.org/x/crypto v0.45.0 // @grafana/grafana-backend-group - golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // @grafana/alerting-backend - golang.org/x/mod v0.30.0 // indirect; @grafana/grafana-backend-group - golang.org/x/net v0.47.0 // @grafana/oss-big-tent @grafana/partner-datasources - golang.org/x/oauth2 v0.33.0 // @grafana/identity-access-team - golang.org/x/sync v0.18.0 // @grafana/alerting-backend - golang.org/x/text v0.31.0 // @grafana/grafana-backend-group + golang.org/x/crypto v0.46.0 // @grafana/grafana-backend-group + golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 // @grafana/alerting-backend + golang.org/x/mod v0.31.0 // indirect; @grafana/grafana-backend-group + golang.org/x/net v0.48.0 // @grafana/oss-big-tent @grafana/partner-datasources + golang.org/x/oauth2 v0.34.0 // @grafana/identity-access-team + golang.org/x/sync v0.19.0 // @grafana/alerting-backend + golang.org/x/text v0.32.0 // @grafana/grafana-backend-group golang.org/x/time v0.14.0 // @grafana/grafana-backend-group - golang.org/x/tools v0.39.0 // indirect; @grafana/grafana-as-code + golang.org/x/tools v0.40.0 // indirect; @grafana/grafana-as-code gonum.org/v1/gonum v0.16.0 // @grafana/oss-big-tent google.golang.org/api v0.242.0 // @grafana/grafana-backend-group google.golang.org/grpc v1.77.0 // @grafana/plugins-platform-backend - google.golang.org/protobuf v1.36.10 // @grafana/plugins-platform-backend + google.golang.org/protobuf v1.36.11 // @grafana/plugins-platform-backend gopkg.in/ini.v1 v1.67.0 // @grafana/alerting-backend gopkg.in/mail.v2 v2.3.1 // @grafana/grafana-backend-group - k8s.io/api v0.34.2 // @grafana/grafana-app-platform-squad - k8s.io/apimachinery v0.34.2 // @grafana/grafana-app-platform-squad - k8s.io/apiserver v0.34.2 // @grafana/grafana-app-platform-squad - k8s.io/client-go v0.34.2 // @grafana/grafana-app-platform-squad - k8s.io/component-base v0.34.2 // @grafana/grafana-app-platform-squad + k8s.io/api v0.34.3 // @grafana/grafana-app-platform-squad + k8s.io/apimachinery v0.34.3 // @grafana/grafana-app-platform-squad + k8s.io/apiserver v0.34.3 // @grafana/grafana-app-platform-squad + k8s.io/client-go v0.34.3 // @grafana/grafana-app-platform-squad + k8s.io/component-base v0.34.3 // @grafana/grafana-app-platform-squad k8s.io/klog/v2 v2.130.1 // @grafana/grafana-app-platform-squad - k8s.io/kube-aggregator v0.34.2 // @grafana/grafana-app-platform-squad - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // @grafana/grafana-app-platform-squad - k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // @grafana/partner-datasources + k8s.io/kube-aggregator v0.34.3 // @grafana/grafana-app-platform-squad + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // @grafana/grafana-app-platform-squad + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // @grafana/partner-datasources modernc.org/sqlite v1.40.1 // @grafana/grafana-backend-group pgregory.net/rapid v1.2.0 // @grafana/grafana-operator-experience-squad sigs.k8s.io/randfill v1.0.0 // @grafana/grafana-app-platform-squad @@ -244,12 +248,12 @@ require ( github.com/grafana/grafana/apps/example v0.0.0-20251027162426-edef69fdc82b // @grafana/grafana-app-platform-squad github.com/grafana/grafana/apps/folder v0.0.0 // @grafana/grafana-search-and-storage github.com/grafana/grafana/apps/iam v0.0.0 // @grafana/identity-access-team - github.com/grafana/grafana/apps/investigations v0.0.0 // @fcjack @matryer github.com/grafana/grafana/apps/logsdrilldown v0.0.0 // @grafana/observability-logs github.com/grafana/grafana/apps/playlist v0.0.0 // @grafana/grafana-app-platform-squad github.com/grafana/grafana/apps/plugins v0.0.0 // @grafana/plugins-platform-backend github.com/grafana/grafana/apps/preferences v0.0.0 // @grafana/grafana-app-platform-squad github.com/grafana/grafana/apps/provisioning v0.0.0 // @grafana/grafana-app-platform-squad + github.com/grafana/grafana/apps/quotas v0.0.0-20251209183543-1013d74f13f2 // @grafana/grafana-search-and-storage github.com/grafana/grafana/apps/scope v0.0.0 // @grafana/grafana-operator-experience-squad github.com/grafana/grafana/apps/secret v0.0.0 // @grafana/grafana-operator-experience-squad github.com/grafana/grafana/apps/shorturl v0.0.0 // @grafana/sharing-squad @@ -277,7 +281,6 @@ replace ( github.com/grafana/grafana/apps/dashboard => ./apps/dashboard github.com/grafana/grafana/apps/folder => ./apps/folder github.com/grafana/grafana/apps/iam => ./apps/iam - github.com/grafana/grafana/apps/investigations => ./apps/investigations github.com/grafana/grafana/apps/logsdrilldown => ./apps/logsdrilldown github.com/grafana/grafana/apps/playlist => ./apps/playlist github.com/grafana/grafana/apps/plugins => ./apps/plugins @@ -294,7 +297,7 @@ replace ( ) require ( - cel.dev/expr v0.24.0 // indirect + cel.dev/expr v0.25.1 // indirect cloud.google.com/go v0.121.4 // indirect cloud.google.com/go/auth v0.16.3 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect @@ -302,7 +305,7 @@ require ( cloud.google.com/go/iam v1.5.2 // indirect cloud.google.com/go/longrunning v0.6.7 // indirect cloud.google.com/go/monitoring v1.24.2 // indirect - cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 // indirect + cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819 // indirect github.com/Azure/azure-pipeline-go v0.2.3 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/keyvault/internal v0.7.1 // indirect @@ -337,23 +340,21 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/at-wat/mqtt-go v0.19.6 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect - github.com/aws/aws-sdk-go-v2/config v1.31.10 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.18.14 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.8 // indirect + github.com/aws/aws-sdk-go-v2/config v1.31.17 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.84 // 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.8 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 // 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/accept-encoding v1.13.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.8 // 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/s3shared v1.18.17 // indirect github.com/aws/aws-sdk-go-v2/service/kms v1.41.2 // indirect github.com/aws/aws-sdk-go-v2/service/s3 v1.84.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.29.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 // indirect github.com/axiomhq/hyperloglog v0.0.0-20240507144631-af9851f82b27 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/barkimedes/go-deepcopy v0.0.0-20220514131651-17c30cfc62df // indirect @@ -385,18 +386,17 @@ require ( github.com/caio/go-tdigest v3.1.0+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // @grafana/alerting-backend github.com/cenkalti/backoff/v5 v5.0.3 // indirect - github.com/centrifugal/protocol v0.16.2 // indirect + github.com/centrifugal/protocol v0.17.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect github.com/chromedp/cdproto v0.0.0-20250803210736-d308e07a266d // indirect - github.com/cloudflare/circl v1.6.1 // indirect github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f // indirect github.com/cockroachdb/apd/v3 v3.2.1 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/coreos/go-semver v0.3.1 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/coreos/go-systemd/v22 v22.6.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dennwc/varint v1.0.0 // indirect @@ -412,7 +412,7 @@ require ( github.com/dolthub/maphash v0.1.0 // indirect github.com/edsrzf/mmap-go v1.2.0 // indirect github.com/elazarl/goproxy v1.7.2 // indirect - github.com/emicklei/proto v1.13.2 // indirect + github.com/emicklei/proto v1.14.2 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect @@ -426,10 +426,10 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.24.0 // indirect github.com/go-openapi/errors v0.22.3 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.2 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/spec v0.22.0 // indirect - github.com/go-openapi/swag v0.23.1 // indirect + github.com/go-openapi/swag v0.25.4 // indirect github.com/go-openapi/validate v0.25.0 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/goccy/go-json v0.10.5 // indirect @@ -444,14 +444,13 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/cel-go v0.26.1 // indirect github.com/google/flatbuffers v25.2.10+incompatible // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-github/v64 v64.0.0 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/grafana/jsonparser v0.0.0-20240425183733-ea80629e1a32 // indirect github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grafana/sqlds/v4 v4.2.7 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/hashicorp/consul/api v1.31.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -488,7 +487,6 @@ require ( github.com/jhump/protoreflect v1.17.0 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect @@ -500,7 +498,7 @@ require ( github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lestrrat-go/strftime v1.0.4 // indirect github.com/magefile/mage v1.15.0 // indirect - github.com/mailru/easyjson v0.9.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/matryer/is v1.4.1 // indirect github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38 // indirect github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect @@ -540,7 +538,6 @@ require ( github.com/oklog/run v1.1.0 // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/oklog/ulid/v2 v2.1.1 // indirect - github.com/open-feature/go-sdk-contrib/providers/ofrep v0.1.6 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.124.1 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/core/xidutils v0.124.1 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.124.1 // indirect @@ -555,13 +552,12 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/pressly/goose/v3 v3.26.0 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.14.0 // indirect - github.com/prometheus/procfs v0.16.1 // indirect - github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d // indirect + github.com/prometheus/procfs v0.19.2 // indirect + github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect - github.com/redis/rueidis v1.0.64 // indirect + github.com/redis/rueidis v1.0.68 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect @@ -594,7 +590,7 @@ require ( github.com/unknwon/log v0.0.0-20200308114134-929b1006e34a // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - github.com/woodsbury/decimal128 v1.3.0 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect @@ -602,10 +598,9 @@ require ( github.com/yuin/gopher-lua v1.1.1 // indirect github.com/zclconf/go-cty v1.16.3 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect - go.etcd.io/bbolt v1.4.2 // indirect - go.etcd.io/etcd/api/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/v3 v3.6.4 // indirect + go.etcd.io/etcd/api/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.6 // indirect + go.etcd.io/etcd/client/v3 v3.6.6 // indirect go.mongodb.org/mongo-driver v1.17.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/featuregate v1.44.0 // indirect @@ -617,29 +612,29 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 // indirect go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.37.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.38.0 // indirect go.opentelemetry.io/otel/log v0.12.2 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect go.opentelemetry.io/otel/sdk/log v0.12.2 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.39.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 // indirect - golang.org/x/term v0.37.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc // indirect + golang.org/x/term v0.38.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect google.golang.org/genproto v0.0.0-20250715232539-7130f93afb79 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect @@ -647,35 +642,40 @@ require ( gopkg.in/telebot.v3 v3.3.8 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.34.2 // indirect - k8s.io/kms v0.34.2 // indirect + k8s.io/apiextensions-apiserver v0.34.3 // indirect + k8s.io/kms v0.34.3 // indirect modernc.org/libc v1.66.10 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect - sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) require github.com/grafana/tempo v1.5.1-0.20250529124718-87c2dc380cec // @grafana/observability-traces-and-profiling require ( - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/IBM/pgxpoolprometheus v1.1.2 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect github.com/cpuguy83/dockercfg v0.3.2 // indirect - github.com/ebitengine/purego v0.8.4 // indirect + github.com/ebitengine/purego v0.8.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-openapi/swag/conv v0.25.1 // indirect - github.com/go-openapi/swag/fileutils v0.25.1 // indirect - github.com/go-openapi/swag/jsonname v0.25.1 // indirect - github.com/go-openapi/swag/jsonutils v0.25.1 // indirect - github.com/go-openapi/swag/loading v0.25.1 // indirect - github.com/go-openapi/swag/mangling v0.25.1 // indirect - github.com/go-openapi/swag/stringutils v0.25.1 // indirect - github.com/go-openapi/swag/typeutils v0.25.1 // indirect - github.com/go-openapi/swag/yamlutils v0.25.1 // indirect + github.com/go-openapi/swag/cmdutils v0.25.4 // indirect + github.com/go-openapi/swag/conv v0.25.4 // indirect + github.com/go-openapi/swag/fileutils v0.25.4 // indirect + github.com/go-openapi/swag/jsonname v0.25.4 // indirect + github.com/go-openapi/swag/jsonutils v0.25.4 // indirect + github.com/go-openapi/swag/loading v0.25.4 // indirect + github.com/go-openapi/swag/mangling v0.25.4 // indirect + github.com/go-openapi/swag/netutils v0.25.4 // indirect + github.com/go-openapi/swag/stringutils v0.25.4 // indirect + github.com/go-openapi/swag/typeutils v0.25.4 // indirect + github.com/go-openapi/swag/yamlutils v0.25.4 // indirect + github.com/google/gnostic v0.7.1 // indirect + github.com/gophercloud/gophercloud/v2 v2.9.0 // indirect + github.com/grafana/sqlds/v5 v5.0.3 // indirect github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect github.com/magiconair/properties v1.8.10 // indirect github.com/moby/go-archive v0.1.0 // indirect @@ -686,7 +686,8 @@ require ( github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect - github.com/shirou/gopsutil/v4 v4.25.6 // indirect + github.com/quagmt/udecimal v1.9.0 // indirect + github.com/shirou/gopsutil/v4 v4.25.3 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect github.com/tklauser/numcpus v0.8.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect diff --git a/go.sum b/go.sum index 91104bfeaf4..0a828108d08 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ buf.build/gen/go/parca-dev/parca/protocolbuffers/go v1.36.2-20250703125925-3f0fc buf.build/gen/go/parca-dev/parca/protocolbuffers/go v1.36.2-20250703125925-3f0fcf4bff96.1/go.mod h1:1M7nlq2ljfzb95x9LaA2j1gYIvDkVZii58mGvTa9ExM= c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805 h1:u2qwJeEvnypw+OCPUHmoZE3IqwfuN5kgDfo5MLzpNM0= c2sp.org/CCTV/age v0.0.0-20240306222714-3ec4d716e805/go.mod h1:FomMrUJ2Lxt5jCLmZkG3FHa72zUprnhd3v/Z18Snm4w= -cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= -cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4= +cel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= @@ -627,11 +627,11 @@ cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoIS cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= -connectrpc.com/connect v1.18.1 h1:PAg7CjSAGvscaf6YZKUefjoih5Z/qYkyaTrBW8xvYPw= -connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= +connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14= +connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w= contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs= -cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 h1:R5wwEcbEZSBmeyg91MJZTxfd7WpBo2jPof3AYjRbxwY= -cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565/go.mod h1:5A4xfTzHTXfeVJBU6RAUf+QrlfTCW+017q/QiW+sMLg= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819 h1:Zh+Ur3OsoWpvALHPLT45nOekHkgOt+IOfutBbPqM17I= +cuelabs.dev/go/oci/ociregistry v0.0.0-20251212221603-3adeb8663819/go.mod h1:WjmQxb+W6nVNCgj8nXrF24lIz95AHwnSl36tpjDZSU8= cuelang.org/go v0.11.1 h1:pV+49MX1mmvDm8Qh3Za3M786cty8VKPWzQ1Ho4gZRP0= cuelang.org/go v0.11.1/go.mod h1:PBY6XvPUswPPJ2inpvUozP9mebDVTXaeehQikhZPBz0= dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= @@ -679,8 +679,7 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.1/go.mod h1:8cl44BDmi+ github.com/Azure/azure-storage-blob-go v0.15.0 h1:rXtgp8tN1p29GvpGgfJetavIG0V7OgcSXPpwp3tx6qk= github.com/Azure/azure-storage-blob-go v0.15.0/go.mod h1:vbjsVbX0dlxnRc4FFMPsS9BsJWPcne7GB7onqlPvz58= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= -github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-autorest v11.2.8+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -760,8 +759,6 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -848,24 +845,24 @@ github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2z github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= 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-v2 v1.39.1 h1:fWZhGAwVRK/fAN2tmt7ilH4PPAE11rDj7HytrmbZ2FE= -github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc= +github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= 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/config v1.31.10 h1:7LllDZAegXU3yk41mwM6KcPu0wmjKGQB1bg99bNdQm4= -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.14 h1:TxkI7QI+sFkTItN/6cJuMZEIVMFXeu2dI1ZffkXngKI= -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.8 h1:gLD09eaJUdiszm7vd1btiQUYE0Hj+0I2b8AS+75z9AY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.8/go.mod h1:4RW3oMPt1POR74qVOC4SbubxAwdP4pCT0nSw3jycOU4= +github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y= +github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c= +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.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= +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.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= 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/internal/configsources v1.4.8 h1:6bgAZgRyT4RoFWhxS+aoGMFyE0cD1bSzFnEEi4bFPGI= -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.8 h1:HhJYoES3zOz34yWEpGENqJvRVPqpmJyR3+AFg9ybhdY= -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.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= -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/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I= +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/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY= +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/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= 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/service/cloudwatch v1.45.3 h1:Nn3qce+OHZuMj/edx4its32uxedAmquCDxtZkrdeiD4= @@ -874,12 +871,12 @@ github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.51.0 h1:e5cbPZYTIY2nUEFie github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs v1.51.0/go.mod h1:UseIHRfrm7PqeZo6fcTb6FUCXzCnh1KJbQbmOfxArGM= github.com/aws/aws-sdk-go-v2/service/ec2 v1.225.2 h1:IfMb3Ar8xEaWjgH/zeVHYD8izwJdQgRP5mKCTDt4GNk= github.com/aws/aws-sdk-go-v2/service/ec2 v1.225.2/go.mod h1:35jGWx7ECvCwTsApqicFYzZ7JFEnBc6oHUuOQ3xIS54= -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.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +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.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= 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/presigned-url v1.13.8 h1:M6JI2aGFEzYxsF6CXIuRBnkge9Wf9a2xU39rNeXgu10= -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/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= +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/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/kms v1.41.2 h1:zJeUxFP7+XP52u23vrp4zMcVhShTWbNO8dHV6xCSvFo= @@ -890,14 +887,16 @@ github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.26.6 h1:Pwbxovp github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.26.6/go.mod h1:Z4xLt5mXspLKjBV92i165wAJ/3T6TIv4n7RtIS8pWV0= 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/sso v1.29.4 h1:FTdEN9dtWPB0EOURNtDPmwGp6GGvMqRJCAihkSl/1No= -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.0 h1:I7ghctfGXrscr7r1Ga/mDqSJKm7Fkpl5Mwq79Z+rZqU= -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.38.5 h1:+LVB0xBqEgjQoqr9bGZbRzvg212B0f17JdflleJRNR4= -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.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= -github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1 h1:w6a0H79HrHf3lr+zrw+pSzR5B+caiQFAKiNHlrUcnoc= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.40.1/go.mod h1:c6Vg0BRiU7v0MVhHupw90RyL120QBwAMLbDCzptGeMk= +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.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= +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.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= +github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= +github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f/go.mod h1:2stgcRjl6QmW+gU2h5E7BQXg4HU0gzxKWDuT5HviN9s= github.com/axiomhq/hyperloglog v0.0.0-20240507144631-af9851f82b27 h1:60m4tnanN1ctzIu4V3bfCNJ39BiOPSm1gHFlFjTkRE0= github.com/axiomhq/hyperloglog v0.0.0-20240507144631-af9851f82b27/go.mod h1:k08r+Yj1PRAmuayFiRK6MYuR5Ve4IuZtTfxErMIh0+c= @@ -982,8 +981,8 @@ github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvF github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous= -github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf h1:TqhNAT4zKbTdLa62d2HDBFdvgSbIGB3eJE8HqhgiL9I= +github.com/bradfitz/gomemcache v0.0.0-20250403215159-8d39553ac7cf/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= @@ -1006,10 +1005,10 @@ github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F9 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/centrifugal/centrifuge v0.37.2 h1:rerQNvDfYN2FZEkVtb/hvGV7SIrJfEQrKF3MaE8GDlo= -github.com/centrifugal/centrifuge v0.37.2/go.mod h1:aj4iRJGhzi3SlL8iUtVezxway1Xf8g+hmNQkLLO7sS8= -github.com/centrifugal/protocol v0.16.2 h1:KoIHgDeX1fFxyxQoKW+6E8ZTCf5mwGm8JyGoJ5NBMbQ= -github.com/centrifugal/protocol v0.16.2/go.mod h1:Q7OpS/8HMXDnL7f9DpNx24IhG96MP88WPpVTTCdrokI= +github.com/centrifugal/centrifuge v0.38.0 h1:UJTowwc5lSwnpvd3vbrTseODbU7osSggN67RTrJ8EfQ= +github.com/centrifugal/centrifuge v0.38.0/go.mod h1:rcZLARnO5GXOeE9qG7iIPMvERxESespqkSX4cGLCAzo= +github.com/centrifugal/protocol v0.17.0 h1:hD0WczyiG7zrVJcgkQsd5/nhfFXt0Y04SJHV2Z7B1rg= +github.com/centrifugal/protocol v0.17.0/go.mod h1:9MdiYyjw5Bw1+d5Sp4Y0NK+qiuTNyd88nrHJsUUh8k4= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -1027,8 +1026,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= -github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -1064,8 +1061,9 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= +github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -1142,8 +1140,8 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= -github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= +github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84= @@ -1156,8 +1154,8 @@ github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVo github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emicklei/proto v1.13.2 h1:z/etSFO3uyXeuEsVPzfl56WNgzcvIr42aQazXaQmFZY= -github.com/emicklei/proto v1.13.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emicklei/proto v1.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I= +github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -1287,16 +1285,16 @@ github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.20.1/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.20.3/go.mod h1:FviDZ46i9ivh810gqzFLl5NttD5q3tSlMLqLr6okedM= github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4= -github.com/go-openapi/jsonreference v0.21.2 h1:Wxjda4M/BBQllegefXrY/9aq1fxBA8sI5M/lFU6tSWU= -github.com/go-openapi/jsonreference v0.21.2/go.mod h1:pp3PEjIsJ9CZDGCNOyXIQxsNuroxm8FAJ/+quA0yKzQ= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= @@ -1336,28 +1334,36 @@ github.com/go-openapi/swag v0.19.4/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-openapi/swag v0.22.6/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= -github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= -github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= -github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0= -github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs= -github.com/go-openapi/swag/fileutils v0.25.1 h1:rSRXapjQequt7kqalKXdcpIegIShhTPXx7yw0kek2uU= -github.com/go-openapi/swag/fileutils v0.25.1/go.mod h1:+NXtt5xNZZqmpIpjqcujqojGFek9/w55b3ecmOdtg8M= -github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= -github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= -github.com/go-openapi/swag/jsonutils v0.25.1 h1:AihLHaD0brrkJoMqEZOBNzTLnk81Kg9cWr+SPtxtgl8= -github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1 h1:DSQGcdB6G0N9c/KhtpYc71PzzGEIc/fZ1no35x4/XBY= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.1/go.mod h1:kjmweouyPwRUEYMSrbAidoLMGeJ5p6zdHi9BgZiqmsg= -github.com/go-openapi/swag/loading v0.25.1 h1:6OruqzjWoJyanZOim58iG2vj934TysYVptyaoXS24kw= -github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc= -github.com/go-openapi/swag/mangling v0.25.1 h1:XzILnLzhZPZNtmxKaz/2xIGPQsBsvmCjrJOWGNz/ync= -github.com/go-openapi/swag/mangling v0.25.1/go.mod h1:CdiMQ6pnfAgyQGSOIYnZkXvqhnnwOn997uXZMAd/7mQ= -github.com/go-openapi/swag/stringutils v0.25.1 h1:Xasqgjvk30eUe8VKdmyzKtjkVjeiXx1Iz0zDfMNpPbw= -github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg= -github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3I3ysiFZqukA= -github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= -github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk= -github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= +github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= github.com/go-openapi/validate v0.22.4/go.mod h1:qm6O8ZIcPVdSY5219468Jv7kBdGvkiZLPOmqnqTUZ2A= @@ -1490,8 +1496,10 @@ github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PU github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic v0.7.1 h1:t5Kc7j/8kYr8t2u11rykRrPPovlEMG4+xdc/SpekATs= +github.com/google/gnostic v0.7.1/go.mod h1:KSw6sxnxEBFM8jLPfJd46xZP+yQcfE8XkiqfZx5zR28= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -1596,9 +1604,8 @@ github.com/googleapis/gnostic v0.3.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gophercloud/gophercloud v0.3.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v1.13.0 h1:8iY9d1DAbzMW6Vok1AxbbK5ZaUjzMp0tdyt4fX9IeJ0= -github.com/gophercloud/gophercloud/v2 v2.6.0 h1:XJKQ0in3iHOZHVAFMXq/OhjCuvvG+BKR0unOqRfG1EI= -github.com/gophercloud/gophercloud/v2 v2.6.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk= +github.com/gophercloud/gophercloud/v2 v2.9.0 h1:Y9OMrwKF9EDERcHFSOTpf/6XGoAI0yOxmsLmQki4LPM= +github.com/gophercloud/gophercloud/v2 v2.9.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= @@ -1613,8 +1620,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= 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/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba h1:psKWNETD5nGxmFAlqnWsXoRyUwSa2GHNEMSEDKGKfQ4= -github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f h1:Br4SaUL3dnVopKKNhDavCLgehw60jdtl/sIxdfzmVts= +github.com/grafana/alerting v0.0.0-20251231150637-b7821017d69f/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/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg= github.com/grafana/authlib/types v0.0.0-20251119142549-be091cf2f4d4 h1:Muoy+FMGrHj3GdFbvsMzUT7eusgii9PKf9L1ZaXDDbY= @@ -1635,12 +1642,12 @@ github.com/grafana/gomemcache v0.0.0-20250318131618-74242eea118d h1:oXRJlb9UjVsl github.com/grafana/gomemcache v0.0.0-20250318131618-74242eea118d/go.mod h1:j/s0jkda4UXTemDs7Pgw/vMT06alWc42CHisvYac0qw= github.com/grafana/grafana-api-golang-client v0.27.0 h1:zIwMXcbCB4n588i3O2N6HfNcQogCNTd/vPkEXTr7zX8= github.com/grafana/grafana-api-golang-client v0.27.0/go.mod h1:uNLZEmgKtTjHBtCQMwNn3qsx2mpMb8zU+7T4Xv3NR9Y= -github.com/grafana/grafana-app-sdk v0.48.5 h1:MS8l9fTZz+VbTfgApn09jw27GxhQ6fNOWGhC4ydvZmM= -github.com/grafana/grafana-app-sdk v0.48.5/go.mod h1:HJsMOSBmt/D/Ihs1SvagOwmXKi0coBMVHlfvdd+qe9Y= -github.com/grafana/grafana-app-sdk/logging v0.48.3 h1:72NUpGNiJXCNQz/on++YSsl38xuVYYBKv5kKQaOClX4= -github.com/grafana/grafana-app-sdk/logging v0.48.3/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= -github.com/grafana/grafana-aws-sdk v1.3.0 h1:/bfJzP93rCel1GbWoRSq0oUo424MZXt8jAp2BK9w8tM= -github.com/grafana/grafana-aws-sdk v1.3.0/go.mod h1:VGycF0JkCGKND2O5je1ucOqPJ0ZNhZYzV3c2bNBAaGk= +github.com/grafana/grafana-app-sdk v0.48.7 h1:9mF7nqkqP0QUYYDlznoOt+GIyjzj45wGfUHB32u2ZMo= +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/go.mod h1:5u3KalezoBAAo2Y3ytDYDAIIPvEqFLLDSxeiK99QxDU= +github.com/grafana/grafana-aws-sdk v1.4.2 h1:GrUEoLbs46r8rG/GZL4L2b63Bo+rkIYKdtCT7kT5KkM= +github.com/grafana/grafana-aws-sdk v1.4.2/go.mod h1:1qnZdYs6gQzxxF0dDodaE7Rn9fiMzuhwvtaAZ7ySnhY= 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-cloud-migration-snapshot v1.9.0 h1:JOzchPgptwJdruYoed7x28lFDwhzs7kssResYsnC0iI= @@ -1653,6 +1660,8 @@ github.com/grafana/grafana-plugin-sdk-go v0.284.0 h1:1bK7eWsnPBLUWDcWJWe218Ik5ad github.com/grafana/grafana-plugin-sdk-go v0.284.0/go.mod h1:lHPniaSxq3SL5MxDIPy04TYB1jnTp/ivkYO+xn5Rz3E= github.com/grafana/grafana/apps/example v0.0.0-20251027162426-edef69fdc82b h1:6Bo65etvjQ4tStkaA5+N3A3ENbO4UAWj53TxF6g2Hdk= github.com/grafana/grafana/apps/example v0.0.0-20251027162426-edef69fdc82b/go.mod h1:6+wASOCN8LWt6FJ8dc0oODUBIEY5XHaE6ABi8g0mR+k= +github.com/grafana/grafana/apps/quotas v0.0.0-20251209183543-1013d74f13f2 h1:rDPMdshj3QMvpXn+wK4T8awF9n2sd8i4YRiGqX2xTvg= +github.com/grafana/grafana/apps/quotas v0.0.0-20251209183543-1013d74f13f2/go.mod h1:M7bV60iRB61y0ISPG1HX/oNLZtlh0ZF22rUYwNkAKjo= github.com/grafana/grafana/pkg/promlib v0.0.8 h1:VUWsqttdf0wMI4j9OX9oNrykguQpZcruudDAFpJJVw0= github.com/grafana/grafana/pkg/promlib v0.0.8/go.mod h1:U1ezG/MGaEPoThqsr3lymMPN5yIPdVTJnDZ+wcXT+ao= github.com/grafana/grafana/pkg/semconv v0.0.0-20250804150913-990f1c69ecc2 h1:A65jWgLk4Re28gIuZcpC0aTh71JZ0ey89hKGE9h543s= @@ -1671,14 +1680,14 @@ github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604 github.com/grafana/prometheus-alertmanager v0.25.1-0.20250911094103-5456b6e45604/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU= github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= -github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae h1:35W3Wjp9KWnSoV/DuymmyIj5aHE0CYlDQ5m2KeXUPAc= -github.com/grafana/pyroscope/api v1.2.1-0.20250415190842-3ff7247547ae/go.mod h1:6CJ1uXmLZ13ufpO9xE4pST+DyaBt0uszzrV0YnoaVLQ= +github.com/grafana/pyroscope/api v1.2.1-0.20251118081820-ace37f973a0f h1:fTlIj5n4x5dU63XHItug7GLjtnaeJdPqBlqg4zlABq0= +github.com/grafana/pyroscope/api v1.2.1-0.20251118081820-ace37f973a0f/go.mod h1:VBNcIhunCZsJ3/mcYx+j7uFf0P/108eiWa+8+Z9ll3o= 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/saml v0.4.15-0.20240917091248-ae3bbdad8a56 h1:SDGrP81Vcd102L3UJEryRd1eestRw73wt+b8vnVEFe0= github.com/grafana/saml v0.4.15-0.20240917091248-ae3bbdad8a56/go.mod h1:S4+611dxnKt8z/ulbvaJzcgSHsuhjVc1QHNTcr1R7Fw= -github.com/grafana/sqlds/v4 v4.2.7 h1:sFQhsS7DBakNMdxa++yOfJ9BVvkZwFJ0B95o57K0/XA= -github.com/grafana/sqlds/v4 v4.2.7/go.mod h1:BQRjUG8rOqrBI4NAaeoWrIMuoNgfi8bdhCJ+5cgEfLU= +github.com/grafana/sqlds/v5 v5.0.3 h1:+yUMUxfa0WANQsmS9xtTFSRX1Q55Iv1B9EjlrW4VlBU= +github.com/grafana/sqlds/v5 v5.0.3/go.mod h1:GKeTTiC+GeR1X0z3f0Iee+hZnNgN62uQpj5XVMx5Uew= github.com/grafana/tempo v1.5.1-0.20250529124718-87c2dc380cec h1:wnzJov9RhSHGaTYGzTygL4qq986fLen8xSqnQgaMd28= github.com/grafana/tempo v1.5.1-0.20250529124718-87c2dc380cec/go.mod h1:j1IY7J2rUz7TcTjFVVx6HCpyTlYOJPtXuGRZ7sI+vSo= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= @@ -1744,8 +1753,6 @@ github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5O github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= -github.com/hashicorp/go-secure-stdlib/plugincontainer v0.4.2 h1:gCNiM4T5xEc4IpT8vM50CIO+AtElr5kO9l2Rxbq+Sz8= -github.com/hashicorp/go-secure-stdlib/plugincontainer v0.4.2/go.mod h1:6ZM4ZdwClyAsiU2uDBmRHCvq0If/03BMbF9U+U7G5pA= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= @@ -1870,10 +1877,6 @@ github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbd github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531 h1:hgVxRoDDPtQE68PT4LFvNlPz2nBKd3OMlGKIQ69OmR4= -github.com/joshlf/go-acl v0.0.0-20200411065538-eae00ae38531/go.mod h1:fqTUQpVYBvhCNIsMXGl2GE9q6z94DIP6NtFKXCSTVbg= -github.com/joshlf/testutil v0.0.0-20170608050642-b5d8aa79d93d h1:J8tJzRyiddAFF65YVgxli+TyWBi0f79Sld6rJP6CBcY= -github.com/joshlf/testutil v0.0.0-20170608050642-b5d8aa79d93d/go.mod h1:b+Q3v8Yrg5o15d71PSUraUzYb+jWl6wQMSBXSGS/hv0= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -1977,8 +1980,8 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= -github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= @@ -2297,8 +2300,8 @@ github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGy github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/common v0.60.1/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= -github.com/prometheus/common v0.67.3 h1:shd26MlnwTw5jksTDhC7rTQIteBxy+ZZDr3t7F2xN2Q= -github.com/prometheus/common v0.67.3/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= +github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc= +github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI= github.com/prometheus/common/assets v0.2.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= @@ -2319,24 +2322,26 @@ github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/prometheus/prometheus v0.0.0-20190818123050-43acd0e2e93f/go.mod h1:rMTlmxGCvukf2KMu3fClMDKLLoJ5hl61MhcJ7xKakf0= github.com/prometheus/prometheus v0.303.1 h1:He/2jRE6sB23Ew38AIoR1WRR3fCMgPlJA2E0obD2WSY= github.com/prometheus/prometheus v0.303.1/go.mod h1:WEq2ogBPZoLjj9x5K67VEk7ECR0nRD9XCjaOt1lsYck= github.com/prometheus/sigv4 v0.1.2 h1:R7570f8AoM5YnTUPFm3mjZH5q2k4D+I/phCWvZ4PXG8= github.com/prometheus/sigv4 v0.1.2/go.mod h1:GF9fwrvLgkQwDdQ5BXeV9XUSCH/IPNqzvAoaohfjqMU= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d h1:HWfigq7lB31IeJL8iy7jkUmU/PG1Sr8jVGhS749dbUA= -github.com/protocolbuffers/txtpbfmt v0.0.0-20241112170944-20d2c9ebc01d/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b h1:fPVI9E6QNFYI0Ph3XpKUDrcAvbCifHvqYJcntFLPog8= +github.com/protocolbuffers/txtpbfmt v0.0.0-20251124094003-fcb97cc64c7b/go.mod h1:JSbkp0BviKovYYt9XunS95M3mLPibE9bGg+Y95DsEEY= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/puzpuzpuz/xsync/v4 v4.2.0 h1:dlxm77dZj2c3rxq0/XNvvUKISAmovoXF4a4qM6Wvkr0= github.com/puzpuzpuz/xsync/v4 v4.2.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= +github.com/quagmt/udecimal v1.9.0 h1:TLuZiFeg0HhS6X8VDa78Y6XTaitZZfh+z5q4SXMzpDQ= +github.com/quagmt/udecimal v1.9.0/go.mod h1:ScmJ/xTGZcEoYiyMMzgDLn79PEJHcMBiJ4NNRT3FirA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE= github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -github.com/redis/rueidis v1.0.64 h1:XqgbueDuNV3qFdVdQwAHJl1uNt90zUuAJuzqjH4cw6Y= -github.com/redis/rueidis v1.0.64/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA= +github.com/redis/rueidis v1.0.68 h1:gept0E45JGxVigWb3zoWHvxEc4IOC7kc4V/4XvN8eG8= +github.com/redis/rueidis v1.0.68/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -2393,8 +2398,8 @@ github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3 h1:/4/IJi5iyTdh6mqOUaASW148HQpujYiHl0Wl78dSOSc= github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3/go.mod h1:aJIMhRsunltJR926EB2MUg8qHemFQDreSB33pyto2Ps= -github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs= -github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c= +github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE= +github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= @@ -2442,8 +2447,8 @@ github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155 github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= -github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0= +github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= +github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -2542,8 +2547,8 @@ github.com/wk8/go-ordered-map v1.0.0 h1:BV7z+2PaK8LTSd/mWgY12HyMAo5CEgkHqbkVq2th github.com/wk8/go-ordered-map v1.0.0/go.mod h1:9ZIbRunKbuvfPKyBP1SIKLcXNlv74YCOZ3t3VTS6gRk= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= @@ -2597,15 +2602,15 @@ gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2 go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= +go.etcd.io/etcd/api/v3 v3.6.6 h1:mcaMp3+7JawWv69p6QShYWS8cIWUOl32bFLb6qf8pOQ= +go.etcd.io/etcd/api/v3 v3.6.6/go.mod h1:f/om26iXl2wSkcTA1zGQv8reJRSLVdoEBsi4JdfMrx4= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= +go.etcd.io/etcd/client/pkg/v3 v3.6.6 h1:uoqgzSOv2H9KlIF5O1Lsd8sW+eMLuV6wzE3q5GJGQNs= +go.etcd.io/etcd/client/pkg/v3 v3.6.6/go.mod h1:YngfUVmvsvOJ2rRgStIyHsKtOt9SZI2aBJrZiWJhCbI= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/client/v3 v3.6.6 h1:G5z1wMf5B9SNexoxOHUGBaULurOZPIgGPsW6CN492ec= +go.etcd.io/etcd/client/v3 v3.6.6/go.mod h1:36Qv6baQ07znPR3+n7t+Rk5VHEzVYPvFfGmfF4wBHV8= go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA= go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE= go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU= @@ -2644,14 +2649,14 @@ go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0 h1:XfzKtKSrbtYk9TNCF8dkO0Y9M7IOfb4idCwBOTwGBiI= go.opentelemetry.io/contrib/exporters/autoexport v0.61.0/go.mod h1:N6otC+qXTD5bAnbK2O1f/1SXq3cX+3KYSWrkBUqG0cw= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0/go.mod h1:rsg1EO8LXSs2po50PB5CeY/MSVlhghuKBgXlKnqm6ks= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0 h1:2pn7OzMewmYRiNtv1doZnLo3gONcnMHlFnmOR8Vgt+8= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.63.0/go.mod h1:rjbQTDEPQymPE0YnRQp9/NuPwwtL0sesz/fnqRW/v84= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0 h1:nXGeLvT1QtCAhkASkP/ksjkTKZALIaQBIW+JSIw1KIc= go.opentelemetry.io/contrib/propagators/jaeger v1.38.0/go.mod h1:oMvOXk78ZR3KEuPMBgp/ThAMDy9ku/eyUVztr+3G6Wo= go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0 h1:oPW/SRFyHgIgxrvNhSBzqvZER2N5kRlci3/rGTOuyWo= @@ -2659,8 +2664,8 @@ go.opentelemetry.io/contrib/samplers/jaegerremote v0.32.0/go.mod h1:B9Oka5QVD0bn go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= -go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4= go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= @@ -2671,12 +2676,12 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0 h1:Oe2z/BCg5q7k4iXC3cqJxKYg0ieRiOqF0cecFYdPTwk= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.38.0/go.mod h1:ZQM5lAJpOsKnYagGg/zV2krVqTtaVdYdDkhMoX6Oalg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0/go.mod h1:ri3aaHSmCTVYu2AWv44YMauwAQc0aqI9gHKIcSbI1pU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4Dc5leUqENgGuQImwLo4WnuXFPetmPpkLi2IrX54= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 h1:aTL7F04bJHUlztTsNGJ2l+6he8c+y/b//eR0jjjemT4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0/go.mod h1:kldtb7jDTeol0l3ewcmd8SDvx3EmIE7lyvqbasU3QC4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.12.2 h1:12vMqzLLNZtXuXbJhSENRg+Vvx+ynNilV8twBLBsXMY= @@ -2690,23 +2695,23 @@ go.opentelemetry.io/otel/log v0.12.2/go.mod h1:ShIItIxSYxufUMt+1H5a2wbckGli3/iCf go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= go.opentelemetry.io/otel/sdk/log v0.12.2 h1:yNoETvTByVKi7wHvYS6HMcZrN5hFLD7I++1xIZ/k6W0= go.opentelemetry.io/otel/sdk/log v0.12.2/go.mod h1:DcpdmUXHJgSqN/dh+XMWa7Vf89u9ap0/AAk/XGLnEzY= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc h1:uqxdywfHqqCl6LmZzI3pUnXT1RGFYyUgxj0AkWPFxi0= go.opentelemetry.io/otel/sdk/log/logtest v0.0.0-20250521073539-a85ae98dcedc/go.mod h1:TY/N/FT7dmFrP/r5ym3g0yysP1DefqGpAZr4f82P0dE= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -2784,8 +2789,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2801,8 +2806,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= -golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9 h1:MDfG8Cvcqlt9XXrmEiD4epKn7VJHZO84hejP9Jmp0MM= +golang.org/x/exp v0.0.0-20251209150349-8475f28825e9/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -2848,8 +2853,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= -golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2935,8 +2940,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2974,8 +2979,8 @@ golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= -golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw= +golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2999,8 +3004,8 @@ golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -3134,11 +3139,11 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo= -golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -3157,8 +3162,8 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= +golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3181,8 +3186,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3267,8 +3272,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= -golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -3517,15 +3522,15 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go. google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba h1:B14OtaXuMaCQsl2deSvNkyPKIzq3BjfxQp8d00QyWx4= -google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= +google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba h1:UKgtfRM7Yh93Sya0Fo8ZzhDP4qBckrrxEr2oF5UIVb8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -3596,8 +3601,8 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -3608,8 +3613,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= @@ -3659,19 +3664,19 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.0.0-20190813020757-36bff7324fb7/go.mod h1:3Iy+myeAORNCLgjd/Xu9ebwN7Vh59Bw0vh9jhoX+V58= -k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= -k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= -k8s.io/apiextensions-apiserver v0.34.2 h1:WStKftnGeoKP4AZRz/BaAAEJvYp4mlZGN0UCv+uvsqo= -k8s.io/apiextensions-apiserver v0.34.2/go.mod h1:398CJrsgXF1wytdaanynDpJ67zG4Xq7yj91GrmYN2SE= +k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4= +k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk= +k8s.io/apiextensions-apiserver v0.34.3 h1:p10fGlkDY09eWKOTeUSioxwLukJnm+KuDZdrW71y40g= +k8s.io/apiextensions-apiserver v0.34.3/go.mod h1:aujxvqGFRdb/cmXYfcRTeppN7S2XV/t7WMEc64zB5A0= k8s.io/apimachinery v0.0.0-20190809020650-423f5d784010/go.mod h1:Waf/xTS2FGRrgXCkO5FP3XxTOWh0qLf2QhL1qFZZ/R8= -k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= -k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/apiserver v0.34.2 h1:2/yu8suwkmES7IzwlehAovo8dDE07cFRC7KMDb1+MAE= -k8s.io/apiserver v0.34.2/go.mod h1:gqJQy2yDOB50R3JUReHSFr+cwJnL8G1dzTA0YLEqAPI= -k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= -k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= -k8s.io/component-base v0.34.2 h1:HQRqK9x2sSAsd8+R4xxRirlTjowsg6fWCPwWYeSvogQ= -k8s.io/component-base v0.34.2/go.mod h1:9xw2FHJavUHBFpiGkZoKuYZ5pdtLKe97DEByaA+hHbM= +k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE= +k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/apiserver v0.34.3 h1:uGH1qpDvSiYG4HVFqc6A3L4CKiX+aBWDrrsxHYK0Bdo= +k8s.io/apiserver v0.34.3/go.mod h1:QPnnahMO5C2m3lm6fPW3+JmyQbvHZQ8uudAu/493P2w= +k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A= +k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM= +k8s.io/component-base v0.34.3 h1:zsEgw6ELqK0XncCQomgO9DpUIzlrYuZYA0Cgo+JWpVk= +k8s.io/component-base v0.34.3/go.mod h1:5iIlD8wPfWE/xSHTRfbjuvUul2WZbI2nOUK65XL0E/c= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= @@ -3679,17 +3684,17 @@ k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.34.2 h1:91rj4MDZLyIT9KxG8J5/CcMH666Z88CF/xJQeuPfJc8= -k8s.io/kms v0.34.2/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= -k8s.io/kube-aggregator v0.34.2 h1:Nn0Vksj67WHBL2x7bJ6vuxL44RbMTK6uRtXX+3vMVJk= -k8s.io/kube-aggregator v0.34.2/go.mod h1:/tp4cc/1p2AvICsS4mjjSJakdrbhcGbRmj0mdHTdR2Q= +k8s.io/kms v0.34.3 h1:QzBOD0sk1bGQVMcZQAHGjtbP1iKZJUyhC6D0I+BTxIE= +k8s.io/kms v0.34.3/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= +k8s.io/kube-aggregator v0.34.3 h1:rKsZWTD2As4dKuv+zzdJU0uo5H7bFlAEoSucai4mW6M= +k8s.io/kube-aggregator v0.34.3/go.mod h1:d4D8PV2FK4Qlq6u442FSum1tHPhK9tKdKBfH/A3R0I0= k8s.io/kube-openapi v0.0.0-20190709113604-33be087ad058/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4= k8s.io/kube-openapi v0.0.0-20190722073852-5e22f3d471e6/go.mod h1:RZvgC8MSN6DjiMV6oIfEE9pDL9CYXokkfaCKZeHm3nc= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/utils v0.0.0-20190809000727-6c36bc71fc4a/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= -k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= @@ -3756,10 +3761,10 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= -sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= diff --git a/go.work b/go.work index ecfab4e96ce..208eca0454a 100644 --- a/go.work +++ b/go.work @@ -17,12 +17,12 @@ use ( ./apps/example ./apps/folder ./apps/iam - ./apps/investigations ./apps/logsdrilldown ./apps/playlist ./apps/plugins ./apps/preferences ./apps/provisioning + ./apps/quotas ./apps/scope ./apps/secret ./apps/shorturl @@ -32,6 +32,7 @@ use ( ./pkg/build ./pkg/build/wire // skip:golangci-lint ./pkg/codegen + ./pkg/plugins ./pkg/plugins/codegen ./pkg/promlib ./pkg/semconv diff --git a/go.work.sum b/go.work.sum index 3017d8eb878..0300e5becbc 100644 --- a/go.work.sum +++ b/go.work.sum @@ -13,6 +13,7 @@ cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= cel.dev/expr v0.19.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cel.dev/expr v0.23.1/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go v0.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= cloud.google.com/go v0.121.0/go.mod h1:rS7Kytwheu/y9buoDmu5EIpMMCI4Mb8ND4aeN4Vwj7Q= cloud.google.com/go v0.121.1/go.mod h1:nRFlrHq39MNVWu+zESP2PosMWA0ryJw8KUBZ2iZpxbw= @@ -279,6 +280,7 @@ github.com/Azure/go-amqp v0.17.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fw github.com/Azure/go-amqp v1.4.0 h1:Xj3caqi4comOF/L1Uc5iuBxR/pB6KumejC01YQOqOR4= github.com/Azure/go-amqp v1.4.0/go.mod h1:vZAogwdrkbyK3Mla8m/CxSc/aKdnTZ4IbPxl51Y5WZE= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 h1:Ov8avRZi2vmrE2JcXw+tu5K/yB41r7xK9GZDiBF7NdM= github.com/Azure/go-autorest/autorest/azure/auth v0.5.13/go.mod h1:5BAVfWLWXihP47vYrPuBKKf4cS0bXI+KM9Qx6ETDJYo= @@ -329,6 +331,8 @@ github.com/KimMachineGun/automemlimit v0.7.1 h1:QcG/0iCOLChjfUweIMC3YL5Xy9C3VBeN github.com/KimMachineGun/automemlimit v0.7.1/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= github.com/MarvinJWendt/testza v0.2.1/go.mod h1:God7bhG8n6uQxwdScay+gjm9/LnO4D3kkcZX4hv9Rp8= github.com/MarvinJWendt/testza v0.2.8/go.mod h1:nwIcjmr0Zz+Rcwfh3/4UhBp7ePKVhuBExvZqnKYWlII= @@ -410,6 +414,7 @@ github.com/apache/arrow/go/v15 v15.0.2/go.mod h1:DGXsR3ajT524njufqf95822i+KTh+ye github.com/apache/thrift v0.21.0/go.mod h1:W1H8aR/QRtYNvrPeFXBtobyRkd0/YVhTc6i07XIAgDw= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= +github.com/at-wat/mqtt-go v0.19.4/go.mod h1:AsiWc9kqVOhqq7LzUeWT/AkKUBfx3Sw5cEe8lc06fqA= github.com/atc0005/go-teams-notify/v2 v2.13.0 h1:nbDeHy89NjYlF/PEfLVF6lsserY9O5SnN1iOIw3AxXw= github.com/atc0005/go-teams-notify/v2 v2.13.0/go.mod h1:WSv9moolRsBcpZbwEf6gZxj7h0uJlJskJq5zkEWKO8Y= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= @@ -419,21 +424,31 @@ github.com/aws/aws-msk-iam-sasl-signer-go v1.0.1 h1:nMp7diZObd4XEVUR0pEvn7/E13JI github.com/aws/aws-msk-iam-sasl-signer-go v1.0.1/go.mod h1:MVYeeOhILFFemC/XlYTClvBjYZrg/EPd3ts885KrNTI= github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= github.com/aws/aws-sdk-go-v2 v1.38.1/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg= +github.com/aws/aws-sdk-go-v2 v1.39.1/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2 v1.39.6/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= github.com/aws/aws-sdk-go-v2/config v1.31.2/go.mod h1:17ft42Yb2lF6OigqSYiDAiUcX4RIkEMY6XxEMJsrAes= +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.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= github.com/aws/aws-sdk-go-v2/credentials v1.18.6/go.mod h1:/jdQkh1iVPa01xndfECInp1v1Wnp70v3K4MvtlLGVEc= +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/dynamodb/attributevalue v1.19.5 h1:oUEqVqonG3xuarrsze1KVJ30KagNYDemikTbdu8KlN8= github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.19.5/go.mod h1:VNM08cHlOsIbSHRqb6D/M2L4kKXfJv3A2/f0GNbOQSc= github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.7.87 h1:oDPArGgCrG/4aTi86ij3S2PB59XXkTSKYVNQlmqRHXQ= github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.7.87/go.mod h1:ZeQC4gVarhdcWeM1c90DyBLaBCNhEeAbKUXwVI/byvw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4/go.mod h1:9xzb8/SV62W6gHQGC/8rrvgNXU6ZoYM3sAIJCIrXJxY= +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.69/go.mod h1:GJj8mmO6YT6EqgduWocwhMoxTLFitkhIrK+owzrYL2I= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.4/go.mod h1:l4bdfCD7XyyZA9BolKBo1eLqgaJxl0/x91PL4Yqe0ao= +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/configsources v1.4.13/go.mod h1:oGnKwIYZ4XttyU2JWxFrwvhF6YKiK/9/wmE3v3Iu9K8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.4/go.mod h1:yDmJgqOiH4EA8Hndnv4KwAo8jCGTSnM5ASG1nBI+toA= +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/endpoints/v2 v2.7.13/go.mod h1:YE94ZoDArI7awZqJzBAZ3PDD2zSfuP7w6P2knOzIn8M= +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.34/go.mod h1:zf7Vcd1ViW7cPqYWEHLHJkS50X0JS2IKz9Cgaj6ugrs= github.com/aws/aws-sdk-go-v2/service/dynamodb v1.44.0 h1:A99gjqZDbdhjtjJVZrmVzVKO2+p3MSg35bDWtbMQVxw= github.com/aws/aws-sdk-go-v2/service/dynamodb v1.44.0/go.mod h1:mWB0GE1bqcVSvpW7OtFA0sKuHk52+IqtnsYU2jUfYAs= @@ -441,11 +456,13 @@ github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.26.0 h1:0wOCTKrmwkyC8Bk7 github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.26.0/go.mod h1:He/RikglWUczbkV+fkdpcV/3GdL/rTRNVy7VaUiezMo= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.0/go.mod h1:eb3gfbVIxIoGgJsi9pGne19dhCBpK6opTYpQqAmdy44= +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.0/go.mod h1:iu6FSzgt+M2/x3Dk8zhycdIcHjEFb36IS8HVUVFoMg0= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.17 h1:x187MqiHwBGjMGAed8Y8K1VGuCtFvQvXb24r+bwmSdo= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.17/go.mod h1:mC9qMbA6e1pwEq6X3zDGtZRXMG2YaElJkbJlMVHLs5I= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.4/go.mod h1:nLEfLnVMmLvyIG58/6gsSA03F1voKGaCfHV7+lR8S7s= +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.15/go.mod h1:ZH34PJUc8ApjBIfgQCFvkWcUDBtl/WTD+uiYHjd8igA= github.com/aws/aws-sdk-go-v2/service/kinesis v1.33.0 h1:JPXkrQk5OS/+Q81fKH97Ll/Vmmy0p9vwHhxw+V+tVjg= github.com/aws/aws-sdk-go-v2/service/kinesis v1.33.0/go.mod h1:dJngkoVMrq0K7QvRkdRZYM4NUp6cdWa2GBdpm8zoY8U= @@ -479,16 +496,22 @@ github.com/aws/aws-sdk-go-v2/service/ssm v1.60.1 h1:OwMzNDe5VVTXD4kGmeK/FtqAITiV github.com/aws/aws-sdk-go-v2/service/ssm v1.60.1/go.mod h1:IyVabkWrs8SNdOEZLyFFcW9bUltV4G6OQS0s6H20PHg= github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= github.com/aws/aws-sdk-go-v2/service/sso v1.28.2/go.mod h1:n9bTZFZcBa9hGGqVz3i/a6+NG0zmZgtkB9qVVFDqPA8= +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.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2/go.mod h1:eknndR9rU8UpE/OmFpqU78V1EcXPKFTTm5l/buZYgvM= +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.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= github.com/aws/aws-sdk-go-v2/service/sts v1.38.0/go.mod h1:bEPcjW7IbolPfK67G1nilqWyoxYMSPrDiIQ3RdIdKgo= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.5/go.mod h1:xoaxeqnnUaZjPjaICgIy5B+MHCSb/ZSOn4MvkFNOUA0= github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw= github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/awslabs/aws-lambda-go-api-proxy v0.16.2 h1:CJyGEyO1CIwOnXTU40urf0mchf6t3voxpvUDikOU9LY= github.com/awslabs/aws-lambda-go-api-proxy v0.16.2/go.mod h1:vxxjwBHe/KbgFeNlAP/Tvp4SsVRL3WQamcWRxqVh0z0= +github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8= +github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/baidubce/bce-sdk-go v0.9.188 h1:8MA7ewe4VpX01uYl7Kic6ZvfIReUFdSKbY46ZqlQM7U= @@ -517,6 +540,7 @@ github.com/bsm/sarama-cluster v2.1.13+incompatible h1:bqU3gMJbWZVxLZ9PGWVKP05yOm github.com/bsm/sarama-cluster v2.1.13+incompatible/go.mod h1:r7ao+4tTNXvWm+VRpRJchr2kQhqxgmAp2iEX5W96gMM= github.com/bufbuild/protovalidate-go v0.2.1 h1:pJr07sYhliyfj/STAM7hU4J3FKpVeLVKvOBmOTN8j+s= github.com/bufbuild/protovalidate-go v0.2.1/go.mod h1:e7XXDtlxj5vlEyAgsrxpzayp4cEMKCSSb8ZCkin+MVA= +github.com/bufbuild/protovalidate-go v0.9.1 h1:cdrIA33994yCcJyEIZRL36ZGTe9UDM/WHs5MBHEimiE= github.com/bufbuild/protovalidate-go v0.9.1/go.mod h1:5jptBxfvlY51RhX32zR6875JfPBRXUsQjyZjm/NqkLQ= github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= @@ -526,6 +550,12 @@ github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/centrifugal/centrifuge v0.37.2/go.mod h1:aj4iRJGhzi3SlL8iUtVezxway1Xf8g+hmNQkLLO7sS8= +github.com/centrifugal/protocol v0.16.2/go.mod h1:Q7OpS/8HMXDnL7f9DpNx24IhG96MP88WPpVTTCdrokI= +github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= +github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= +github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= +github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= @@ -545,12 +575,14 @@ github.com/cilium/ebpf v0.9.1/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnx github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c h1:2zRrJWIt/f9c9HhNHAgrRgq0San5gRRUJTBXLkchal0= +github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= @@ -558,6 +590,7 @@ github.com/coder/quartz v0.1.0 h1:cLL+0g5l7xTf6ordRnUMMiZtRE8Sq5LxpghS63vEXrQ= github.com/coder/quartz v0.1.0/go.mod h1:vsiCc+AHViMKH2CQpGIpFgdHIEQsxwm8yCscqKmzbRA= github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= +github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/containerd/btrfs/v2 v2.0.0/go.mod h1:swkD/7j9HApWpzl8OHfrHNxppPd9l44DFZdF94BUj9k= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= @@ -680,8 +713,7 @@ github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6 github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 h1:Oy0F4ALJ04o5Qqpdz8XLIpNA3WM/iSIXqxtqo7UGVws= github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3/go.mod h1:YvSRo5mw33fLEx1+DlK6L2VV43tJt5Eyel9n9XBcR+0= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= -github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= -github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b h1:ZHiD4/yE4idlbqvAO6iYCOYRzOMRpxkW+FKasRA3tsQ= github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b/go.mod h1:OmVcnJopJL8d3X3sSXTiypGoUSgFq1aDGmlrdi9dn/M= github.com/elastic/elastic-transport-go/v8 v8.6.1 h1:h2jQRqH6eLGiBSN4eZbQnJLtL4bC5b4lfVFRjw2R4e4= @@ -710,8 +742,11 @@ github.com/envoyproxy/go-control-plane/envoy v1.32.3/go.mod h1:F6hWupPfh75TBXGKA github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= +github.com/ericlagergren/decimal v0.0.0-20240411145413-00de7ca16731 h1:R/ZjJpjQKsZ6L/+Gf9WHbt31GG8NMVcpRqUE+1mMIyo= +github.com/ericlagergren/decimal v0.0.0-20240411145413-00de7ca16731/go.mod h1:M9R1FoZ3y//hwwnJtO51ypFGwm8ZfpxPT/ZLtO1mcgQ= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= +github.com/expr-lang/expr v1.17.6/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= @@ -722,6 +757,8 @@ github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZP github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= +github.com/flowstack/go-jsonschema v0.1.1 h1:dCrjGJRXIlbDsLAgTJZTjhwUJnnxVWl1OgNyYh5nyDc= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/fluent/fluent-bit-go v0.0.0-20230731091245-a7a013e2473c h1:yKN46XJHYC/gvgH2UsisJ31+n4K3S7QYZSfU2uAWjuI= github.com/fluent/fluent-bit-go v0.0.0-20230731091245-a7a013e2473c/go.mod h1:L92h+dgwElEyUuShEwjbiHjseW410WIcNz+Bjutc8YQ= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= @@ -761,6 +798,7 @@ github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo= @@ -775,6 +813,15 @@ github.com/go-openapi/loads v0.22.0/go.mod h1:yLsaTCS92mnSAZX5WWoxszLj0u+Ojl+Zs5 github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= +github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs= +github.com/go-openapi/swag/fileutils v0.25.1/go.mod h1:+NXtt5xNZZqmpIpjqcujqojGFek9/w55b3ecmOdtg8M= +github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo= +github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc= +github.com/go-openapi/swag/mangling v0.25.1/go.mod h1:CdiMQ6pnfAgyQGSOIYnZkXvqhnnwOn997uXZMAd/7mQ= +github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg= +github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= +github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ= github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= @@ -797,6 +844,7 @@ github.com/gocql/gocql v1.7.0/go.mod h1:vnlvXyFZeLBF0Wy+RS8hrOdbn0UWsWtdg07XJnFx github.com/gocraft/dbr/v2 v2.7.2 h1:ccUxMuz6RdZvD7VPhMRRMSS/ECF3gytPhPtcavjktHk= github.com/gocraft/dbr/v2 v2.7.2/go.mod h1:5bCqyIXO5fYn3jEp/L06QF4K1siFdhxChMjdNu6YJrg= github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= @@ -847,6 +895,7 @@ github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQ github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/gophercloud/gophercloud v1.13.0 h1:8iY9d1DAbzMW6Vok1AxbbK5ZaUjzMp0tdyt4fX9IeJ0= github.com/gophercloud/gophercloud v1.13.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= @@ -856,10 +905,13 @@ github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkM github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grafana/alerting v0.0.0-20250729175202-b4b881b7b263/go.mod h1:VKxaR93Gff0ZlO2sPcdPVob1a/UzArFEW5zx3Bpyhls= +github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM= github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43/go.mod h1:1fWkOiL+m32NBgRHZtlZGz2ji868tPZACYbqP3nBRJI= github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43/go.mod h1:qeWYbnWzaYGl88JlL9+DsP1GT2Cudm58rLtx13fKZdw= +github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37/go.mod h1:qeWYbnWzaYGl88JlL9+DsP1GT2Cudm58rLtx13fKZdw= github.com/grafana/cloudflare-go v0.0.0-20230110200409-c627cf6792f2 h1:qhugDMdQ4Vp68H0tp/0iN17DM2ehRo1rLEdOFe/gB8I= github.com/grafana/cloudflare-go v0.0.0-20230110200409-c627cf6792f2/go.mod h1:w/aiO1POVIeXUQyl0VQSZjl5OAGDTL5aX+4v0RA1tcw= +github.com/grafana/codejen v0.0.4-0.20230321061741-77f656893a3d/go.mod h1:zmwwM/DRyQB7pfuBjTWII3CWtxcXh8LTwAYGfDfpR6s= github.com/grafana/cog v0.0.43/go.mod h1:TDunc7TYF7EfzjwFOlC5AkMe3To/U2KqyyG3QVvrF38= github.com/grafana/dskit v0.0.0-20250611075409-46f51e1ce914/go.mod h1:OiN4P4aC6LwLzLbEupH3Ue83VfQoNMfG48rsna8jI/E= github.com/grafana/dskit v0.0.0-20250818234656-8ff9c6532e85/go.mod h1:kImsvJ1xnmeT9Z6StK+RdEKLzlpzBsKwJbEQfmBJdFs= @@ -873,7 +925,6 @@ github.com/grafana/grafana-app-sdk v0.41.0 h1:SYHN3U7B1myRKY3UZZDkFsue9TDmAOap0U github.com/grafana/grafana-app-sdk v0.41.0/go.mod h1:Wg/3vEZfok1hhIWiHaaJm+FwkosfO98o8KbeLFEnZpY= github.com/grafana/grafana-app-sdk v0.46.0/go.mod h1:LCTrqR1SwBS13XGVYveBmM7giJDDjzuXK+M9VzPuPWc= github.com/grafana/grafana-app-sdk v0.47.0/go.mod h1:kywXmkppq0oReUMzkjTW8Fq2EBzyN7v914jttTWnWxA= -github.com/grafana/grafana-app-sdk v0.48.2/go.mod h1:LDOvQ7OOyHLcXdSa0InATCa5OMoYAd6E1+rGLrMgHuk= github.com/grafana/grafana-app-sdk/logging v0.38.0/go.mod h1:Y/bvbDhBiV/tkIle9RW49pgfSPIPSON8Q4qjx3pyqDk= github.com/grafana/grafana-app-sdk/logging v0.39.0 h1:3GgN5+dUZYqq74Q+GT9/ET+yo+V54zWQk/Q2/JsJQB4= github.com/grafana/grafana-app-sdk/logging v0.39.0/go.mod h1:WhDENSnaGHtyVVwZGVnAR7YLvh2xlLDYR3D7E6h7XVk= @@ -887,9 +938,10 @@ github.com/grafana/grafana-app-sdk/logging v0.45.0/go.mod h1:Gh/nBWnspK3oDNWtiM5 github.com/grafana/grafana-app-sdk/logging v0.46.0/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= github.com/grafana/grafana-app-sdk/logging v0.48.0 h1:xolkQxBlA2LQF4hprKIAeu+zUem1DigYZ6XC1TOhFJE= github.com/grafana/grafana-app-sdk/logging v0.48.0/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= -github.com/grafana/grafana-app-sdk/logging v0.48.1/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= github.com/grafana/grafana-app-sdk/logging v0.48.2 h1:tI+a9slUvxKUgweXDzUqkca2LWV3g1UdaSvwt8nQNHg= github.com/grafana/grafana-app-sdk/logging v0.48.2/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= +github.com/grafana/grafana-app-sdk/logging v0.48.5 h1:vWiTZrsSscbC5IQq2heWXm0dXhvg40nXIeUTCdE9qsc= +github.com/grafana/grafana-app-sdk/logging v0.48.5/go.mod h1:Gh/nBWnspK3oDNWtiM5qUF/fardHzOIEez+SPI3JeHA= github.com/grafana/grafana-app-sdk/plugin v0.41.0 h1:ShUvGpAVzM3UxcsfwS6l/lwW4ytDeTbCQXf8w2P8Yp8= github.com/grafana/grafana-app-sdk/plugin v0.41.0/go.mod h1:YIhimVfAqtOp3kdhxOanaSZjypVKh/bYxf9wfFfhDm0= github.com/grafana/grafana-aws-sdk v0.38.2 h1:TzQD0OpWsNjtldi5G5TLDlBRk8OyDf+B5ujcoAu4Dp0= @@ -898,6 +950,7 @@ github.com/grafana/grafana-aws-sdk v1.0.2 h1:98eBuHYFmgvH0xO9kKf4RBsEsgQRp8EOA/9 github.com/grafana/grafana-aws-sdk v1.0.2/go.mod h1:hO7q7yWV+t6dmiyJjMa3IbuYnYkBua+G/IAlOPVIYKE= github.com/grafana/grafana-aws-sdk v1.1.0/go.mod h1:7e+47EdHynteYWGoT5Ere9KeOXQObsk8F0vkOLQ1tz8= github.com/grafana/grafana-aws-sdk v1.2.0/go.mod h1:bBo7qOmM3f61vO+2JxTolNUph1l2TmtzmWcU9/Im+8A= +github.com/grafana/grafana-aws-sdk v1.3.0/go.mod h1:VGycF0JkCGKND2O5je1ucOqPJ0ZNhZYzV3c2bNBAaGk= github.com/grafana/grafana-azure-sdk-go/v2 v2.1.6/go.mod h1:V7y2BmsWxS3A9Ohebwn4OiSfJJqi//4JQydQ8fHTduo= github.com/grafana/grafana-azure-sdk-go/v2 v2.2.0/go.mod h1:H9sVh9A4yg5egMGZeh0mifxT1Q/uqwKe1LBjBJU6pN8= github.com/grafana/grafana-plugin-sdk-go v0.263.0/go.mod h1:U43Cnrj/9DNYyvFcNdeUWNjMXTKNB0jcTcQGpWKd2gw= @@ -908,6 +961,7 @@ github.com/grafana/grafana-plugin-sdk-go v0.277.0/go.mod h1:mAUWg68w5+1f5TLDqagI github.com/grafana/grafana-plugin-sdk-go v0.278.0/go.mod h1:+8NXT/XUJ/89GV6FxGQ366NZ3nU+cAXDMd0OUESF9H4= github.com/grafana/grafana-plugin-sdk-go v0.279.0/go.mod h1:/7oGN6Z7DGTGaLHhgIYrRr6Wvmdsb3BLw5hL4Kbjy88= github.com/grafana/grafana-plugin-sdk-go v0.280.0/go.mod h1:Z15Wiq3c4I0tzHYrLYpOqrO8u3+2RJ+HN2Q9uiZTILA= +github.com/grafana/grafana-plugin-sdk-go v0.281.0/go.mod h1:3I0g+v6jAwVmrt6BEjDUP4V6pkhGP5QKY5NkXY4Ayr4= github.com/grafana/grafana-plugin-sdk-go v0.283.0/go.mod h1:20qhoYxIgbZRmwCEO1KMP8q2yq/Kge5+xE/99/hLEk0= github.com/grafana/grafana/apps/advisor v0.0.0-20250123151950-b066a6313173/go.mod h1:goSDiy3jtC2cp8wjpPZdUHRENcoSUHae1/Px/MDfddA= github.com/grafana/grafana/apps/advisor v0.0.0-20250220154326-6e5de80ef295/go.mod h1:9I1dKV3Dqr0NPR9Af0WJGxOytp5/6W3JLiNChOz8r+c= @@ -926,6 +980,7 @@ github.com/grafana/grafana/apps/preferences v0.0.0-20250805120145-0c5a00302924 h github.com/grafana/grafana/apps/preferences v0.0.0-20250805120145-0c5a00302924/go.mod h1:NQlHMO5fHhjexw71wVjv522532NRvFg5F4tcjUEktjs= github.com/grafana/grafana/apps/preferences v0.0.0-20250805123034-066163d71001 h1:y2AHkdji2I+zXv8rsSC8OjWEzJJjqW5OlmCsZR5+RuU= github.com/grafana/grafana/apps/preferences v0.0.0-20250805123034-066163d71001/go.mod h1:NQlHMO5fHhjexw71wVjv522532NRvFg5F4tcjUEktjs= +github.com/grafana/grafana/apps/quotas v0.0.0-20251209171149-4b999cd94388/go.mod h1:M7bV60iRB61y0ISPG1HX/oNLZtlh0ZF22rUYwNkAKjo= github.com/grafana/grafana/pkg/aggregator v0.0.0-20250121113133-e747350fee2d/go.mod h1:1sq0guad+G4SUTlBgx7SXfhnzy7D86K/LcVOtiQCiMA= github.com/grafana/grafana/pkg/semconv v0.0.0-20250121113133-e747350fee2d/go.mod h1:tfLnBpPYgwrBMRz4EXqPCZJyCjEG4Ev37FSlXnocJ2c= github.com/grafana/grafana/pkg/storage/unified/apistore v0.0.0-20250121113133-e747350fee2d/go.mod h1:CXpwZ3Mkw6xVlGKc0SqUxqXCP3Uv182q6qAQnLaLxRg= @@ -943,6 +998,7 @@ github.com/grafana/prometheus-alertmanager v0.25.1-0.20250604130045-92c8f6389b36 github.com/grafana/prometheus-alertmanager v0.25.1-0.20250604130045-92c8f6389b36/go.mod h1:O/QP1BCm0HHIzbKvgMzqb5sSyH88rzkFk84F4TfJjBU= github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/grafana/sqlds/v4 v4.2.4/go.mod h1:BQRjUG8rOqrBI4NAaeoWrIMuoNgfi8bdhCJ+5cgEfLU= +github.com/grafana/sqlds/v4 v4.2.7/go.mod h1:BQRjUG8rOqrBI4NAaeoWrIMuoNgfi8bdhCJ+5cgEfLU= github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0 h1:bjh0PVYSVVFxzINqPFYJmAmJNrWPgnVjuSdYJGHmtFU= github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0/go.mod h1:7t5XR+2IA8P2qggOAHTj/GCZfoLBle3OvNSYh1VkRBU= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= @@ -951,12 +1007,12 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= @@ -1295,6 +1351,7 @@ github.com/open-telemetry/opentelemetry-collector-contrib/receiver/opencensusrec github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.121.0/go.mod h1:3axnebi8xUm9ifbs1myzehw2nODtIMrQlL566sJ4bYw= github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.124.1 h1:XkxqUEoukMWXF+EpEWeM9itXKt62yKi13Lzd8ZEASP4= github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceiver v0.124.1/go.mod h1:CuCZVPz+yn88b5vhZPAlxaMrVuhAVexUV6f8b07lpUc= +github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -1332,6 +1389,7 @@ github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgc github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs= github.com/pkg/xattr v0.4.10 h1:Qe0mtiNFHQZ296vRgUjRCoPHPqH7VdTOrZx3g0T+pGA= github.com/pkg/xattr v0.4.10/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= +github.com/planetscale/vtprotobuf v0.6.0/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= @@ -1346,6 +1404,7 @@ github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkq github.com/prometheus/common v0.64.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/common v0.67.1/go.mod h1:RpmT9v35q2Y+lsieQsdOh5sXZ6ajUGC8NjZAmr8vb0Q= github.com/prometheus/common v0.67.2/go.mod h1:63W3KZb1JOKgcjlIr64WW/LvFGAqKPj0atm+knVGEko= github.com/prometheus/common/assets v0.2.0 h1:0P5OrzoHrYBOSM1OigWL3mY8ZvV2N4zIE/5AahrSrfM= github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97/go.mod h1:LoBCZeRh+5hX+fSULNyFnagYlQG/gBsyA/deNzROkq8= @@ -1368,6 +1427,7 @@ github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/redis/rueidis v1.0.64/go.mod h1:Lkhr2QTgcoYBhxARU7kJRO8SyVlgUuEkcJO1Y8MCluA= github.com/relvacode/iso8601 v1.6.0 h1:eFXUhMJN3Gz8Rcq82f9DTMW0svjtAVuIEULglM7QHTU= github.com/relvacode/iso8601 v1.6.0/go.mod h1:FlNp+jz+TXpyRqgmM7tnzHHzBnz776kmAH2h3sZCn0I= github.com/richardartoul/molecule v1.0.0 h1:+LFA9cT7fn8KF39zy4dhOnwcOwRoqKiBkPqKqya+8+U= @@ -1375,7 +1435,6 @@ github.com/richardartoul/molecule v1.0.0/go.mod h1:uvX/8buq8uVeiZiFht+0lqSLBHF+u github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= @@ -1387,6 +1446,8 @@ github.com/sagikazarmark/crypt v0.6.0 h1:REOEXCs/NFY/1jOCEouMuT4zEniE5YoXbvpC5X/ github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= +github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/samber/slog-common v0.18.1 h1:c0EipD/nVY9HG5shgm/XAs67mgpWDMF+MmtptdJNCkQ= @@ -1400,6 +1461,7 @@ github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtm github.com/schollz/progressbar/v3 v3.14.6 h1:GyjwcWBAf+GFDMLziwerKvpuS7ZF+mNTAXIB2aspiZs= github.com/schollz/progressbar/v3 v3.14.6/go.mod h1:Nrzpuw3Nl0srLY0VlTvC4V6RL50pcEymjy6qyJAaLa0= github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= +github.com/segmentio/asm v1.1.4/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/segmentio/parquet-go v0.0.0-20220811205829-7efc157d28af/go.mod h1:PxYdAI6cGd+s1j4hZDQbz3VFgobF5fDA0weLeNWKTE4= @@ -1412,8 +1474,6 @@ github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKl github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= -github.com/shirou/gopsutil/v4 v4.25.3 h1:SeA68lsu8gLggyMbmCn8cmp97V1TI9ld9sVzAUcKcKE= -github.com/shirou/gopsutil/v4 v4.25.3/go.mod h1:xbuxyoZj+UsgnZrENu3lQivsngRR5BdjbJwf2fv4szA= github.com/shirou/gopsutil/v4 v4.25.5/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= @@ -1593,7 +1653,6 @@ go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5queth go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.mongodb.org/mongo-driver v1.17.3/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/collector v0.121.0/go.mod h1:M4TlnmkjIgishm2DNCk9K3hMKTmAsY9w8cNFsp9EchM= go.opentelemetry.io/collector v0.124.0/go.mod h1:QzERYfmHUedawjr8Ph/CBEEkVqWS8IlxRLAZt+KHlCg= go.opentelemetry.io/collector/client v1.29.0/go.mod h1:LCUoEV2KCTKA1i+/txZaGsSPVWUcqeOV6wCfNsAippE= @@ -1800,6 +1859,7 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.62.0/go.mod h1:ru6KHrNtNHxM4nD/vd6QrLVWgKhxPYgblq4VAtNawTQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.61.0/go.mod h1:HfvuU0kW9HewH14VCOLImqKvUgONodURG7Alj/IrnGI= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.62.0/go.mod h1:WfEApdZDMlLUAev/0QQpr8EJ/z0VWDKYZ5tF5RH5T1U= @@ -1809,6 +1869,7 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1: go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= go.opentelemetry.io/contrib/otelconf v0.15.0 h1:BLNiIUsrNcqhSKpsa6CnhE6LdrpY1A8X0szMVsu99eo= go.opentelemetry.io/contrib/otelconf v0.15.0/go.mod h1:OPH1seO5z9dp1P26gnLtoM9ht7JDvh3Ws6XRHuXqImY= go.opentelemetry.io/contrib/propagators/aws v1.37.0 h1:cp8AFiM/qjBm10C/ATIRnEDXpD5MBknrA0ANw4T2/ss= @@ -1850,7 +1911,6 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0/go.mod h1:hYwym2nDEeZfG/motx0p7L7J1N1vyzIThemQsb4g2qY= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= go.opentelemetry.io/otel/exporters/prometheus v0.58.0/go.mod h1:7qo/4CLI+zYSNbv0GMNquzuss2FVZo3OYrGh96n4HNc= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0/go.mod h1:PD57idA/AiFD5aqoxGxCvT/ILJPeHy3MjqU/NS7KogY= @@ -1880,10 +1940,10 @@ go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v8 go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc= go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= @@ -1894,10 +1954,12 @@ gocloud.dev/secrets/hashivault v0.42.0/go.mod h1:LXprr1XLEAT7BVZ+Y66dJEHQMzDsowI golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.11.1-0.20230711161743-2e82bdd1719d/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= @@ -1905,6 +1967,7 @@ golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632 golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= @@ -1918,6 +1981,7 @@ golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5N golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/exp v0.0.0-20250811191247-51f88131bc50/go.mod h1:rT6SFzZ7oxADUDx58pcaKFTcZ+inxAa9fTrYx/uVYwg= +golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM= golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= @@ -1925,6 +1989,7 @@ golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mod v0.6.0-dev.0.20220818022119-ed83ed61efb9/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= @@ -1936,12 +2001,14 @@ golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= @@ -2000,6 +2067,7 @@ golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20250908211612-aef8a434d053/go.mod h1:+nZKN+XVh4LCiA9DV3ywrzN4gumyCnKjau3NGb9SGoE= +golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= @@ -2008,6 +2076,8 @@ golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0= golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= @@ -2022,15 +2092,16 @@ golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/tools v0.24.1/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= @@ -2081,11 +2152,12 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go. google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b/go.mod h1:oDOGiMSXHL4sDTJvFvIB9nRQCGdLP1o/iVaqQK8zB+M= google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c/go.mod h1:ea2MjsO70ssTfCjiwHgI0ZFqcw45Ksuk2ckf9G468GA= google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090/go.mod h1:U8EXRNSd8sUYyDfs/It7KVWodQr+Hf9xtxyxWudSwEw= google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk= -google.golang.org/genproto/googleapis/api v0.0.0-20251022142026-3a174f9686a8/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= +google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:G5IanEx8/PgI9w6CFcYQf7jMtHQhZruvfM1i3qOqk5U= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= google.golang.org/genproto/googleapis/bytestream v0.0.0-20250603155806-513f23925822 h1:zWFRixYR5QlotL+Uv3YfsPRENIrQFXiGs+iwqel6fOQ= google.golang.org/genproto/googleapis/bytestream v0.0.0-20250603155806-513f23925822/go.mod h1:h6yxum/C2qRb4txaZRLDHK8RyS0H/o2oEDeKY4onY/Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= google.golang.org/genproto/googleapis/rpc v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:oQ5rr10WTTMvP4A36n8JpR1OrO1BEiV4f78CneXZxkA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= @@ -2112,12 +2184,15 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go. google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og= google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251002232023-7c0ddcbb5797/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20251014184007-4626949a642f/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251111163417-95abcf5c77ba/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= @@ -2135,7 +2210,6 @@ google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7E google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20 h1:MLBCGN1O7GzIx+cBiwfYPwtmZ41U3Mn/cotLJciaArI= google.golang.org/grpc/examples v0.0.0-20230224211313-3775f633ce20/go.mod h1:Nr5H8+MlGWr5+xX/STzdoEqJrO+YteqFbMyCsrb6mH0= @@ -2167,7 +2241,6 @@ gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzE gopkg.in/vmihailenco/msgpack.v2 v2.9.2 h1:gjPqo9orRVlSAH/065qw3MsFCDpH7fa1KpiizXyllY4= gopkg.in/vmihailenco/msgpack.v2 v2.9.2/go.mod h1:/3Dn1Npt9+MYyLpYYXjInO/5jvMLamn+AEGwNEOatn8= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= -gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34= honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= @@ -2179,30 +2252,37 @@ k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE= k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug= k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk= k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8= +k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc= k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8= k8s.io/apiserver v0.33.3/go.mod h1:05632ifFEe6TxwjdAIrwINHWE2hLwyADFk5mBsQa15E= +k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0= k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg= k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY= k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8= -k8s.io/code-generator v0.34.1 h1:WpphT26E+j7tEgIUfFr5WfbJrktCGzB3JoJH9149xYc= -k8s.io/code-generator v0.34.1/go.mod h1:DeWjekbDnJWRwpw3s0Jat87c+e0TgkxoR4ar608yqvg= -k8s.io/code-generator v0.34.2 h1:9bG6jTxmsU3HXE5BNYJTC8AZ1D6hVVfkm8yYSkdkGY0= -k8s.io/code-generator v0.34.2/go.mod h1:dnDDEd6S/z4uZ+PG1aE58ySCi/lR4+qT3a4DddE4/2I= +k8s.io/code-generator v0.34.3 h1:6ipJKsJZZ9q21BO8I2jEj4OLN3y8/1n4aihKN0xKmQk= +k8s.io/code-generator v0.34.3/go.mod h1:oW73UPYpGLsbRN8Ozkhd6ZzkF8hzFCiYmvEuWZDroI4= k8s.io/component-base v0.26.2/go.mod h1:DxbuIe9M3IZPRxPIzhch2m1eT7uFrSBJUBuVCQEBivs= k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4= +k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0= k8s.io/cri-api v0.27.1/go.mod h1:+Ts/AVYbIo04S86XbTD73UPp/DkTiYxtsFeOFEu32L0= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6 h1:4s3/R4+OYYYUKptXPhZKjQ04WJ6EhQQVFdjOFvCazDk= k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f h1:SLb+kxmzfA87x4E4brQzB33VBbT2+x7Zq9ROIHmGn9Q= k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= +k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b h1:gMplByicHV/TJBizHd9aVEsTYoJBnnUAT5MHlTkbjhQ= +k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b/go.mod h1:CgujABENc3KuTrcsdpGmrrASjtQsWCT7R99mEV4U/fM= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kms v0.34.1/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= +k8s.io/kube-aggregator v0.34.1/go.mod h1:RU8j+5ERfp0h+gIvWtxRPfsa5nK7rboDm8RST8BJfYQ= k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= @@ -2250,7 +2330,6 @@ sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ih sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk= sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/structured-merge-diff/v6 v6.2.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4= diff --git a/hack/go.mod b/hack/go.mod index e9ecfdc60b4..57179bc0550 100644 --- a/hack/go.mod +++ b/hack/go.mod @@ -2,7 +2,7 @@ module github.com/grafana/grafana/hack go 1.25.5 -require k8s.io/code-generator v0.34.2 +require k8s.io/code-generator v0.34.3 require ( github.com/go-logr/logr v1.4.2 // indirect diff --git a/hack/go.sum b/hack/go.sum index 25c035d777a..b427dbd73ef 100644 --- a/hack/go.sum +++ b/hack/go.sum @@ -12,8 +12,8 @@ golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= -k8s.io/code-generator v0.34.2 h1:9bG6jTxmsU3HXE5BNYJTC8AZ1D6hVVfkm8yYSkdkGY0= -k8s.io/code-generator v0.34.2/go.mod h1:dnDDEd6S/z4uZ+PG1aE58ySCi/lR4+qT3a4DddE4/2I= +k8s.io/code-generator v0.34.3 h1:6ipJKsJZZ9q21BO8I2jEj4OLN3y8/1n4aihKN0xKmQk= +k8s.io/code-generator v0.34.3/go.mod h1:oW73UPYpGLsbRN8Ozkhd6ZzkF8hzFCiYmvEuWZDroI4= k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f h1:SLb+kxmzfA87x4E4brQzB33VBbT2+x7Zq9ROIHmGn9Q= k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 59976c9bf3c..03dd95943a2 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -11,7 +11,7 @@ set -o pipefail SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. pushd "${SCRIPT_ROOT}/hack" && GO111MODULE=on go mod tidy && popd -CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo $(go env GOPATH)/pkg/mod/k8s.io/code-generator@v0.34.2)} +CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo $(go env GOPATH)/pkg/mod/k8s.io/code-generator@v0.34.3)} OUTDIR="${HOME}/go/src" OPENAPI_VIOLATION_EXCEPTIONS_FILENAME="zz_generated.openapi_violation_exceptions.list" diff --git a/jest.config.js b/jest.config.js index ef107c8cc24..17a2ce9ca32 100644 --- a/jest.config.js +++ b/jest.config.js @@ -40,6 +40,9 @@ const esModules = [ module.exports = { verbose: false, testEnvironment: 'jsdom', + testEnvironmentOptions: { + customExportConditions: ['@grafana-app/source', 'browser'], + }, transform: { '^.+\\.(ts|tsx|js|jsx)$': [require.resolve('ts-jest')], }, diff --git a/kinds/dashboard/dashboard_kind.cue b/kinds/dashboard/dashboard_kind.cue index 346edbb4753..f17aa67f209 100644 --- a/kinds/dashboard/dashboard_kind.cue +++ b/kinds/dashboard/dashboard_kind.cue @@ -218,6 +218,10 @@ lineage: schemas: [{ // 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. regex?: string + // Optional, indicates whether a custom type variable uses CSV or JSON to define its values + valuesFormat?: "csv" | "json" | *"csv" + // Determine whether regex applies to variable value or display text + regexApplyTo?: #VariableRegexApplyTo // Additional static options for query variable staticOptions?: [...#VariableOption] // Ordering of static options in relation to options returned from data source for query variable @@ -245,6 +249,10 @@ lineage: schemas: [{ // Accepted values are 0 (show label and value), 1 (show value only), 2 (show nothing), 3 (show under the controls dropdown menu). #VariableHide: 0 | 1 | 2 | 3 @cuetsy(kind="enum",memberNames="dontHide|hideLabel|hideVariable|inControlsMenu") @grafana(TSVeneer="type") + // Determine whether regex applies to variable value or display text + // Accepted values are "value" (apply to value used in queries) or "text" (apply to display text shown to users) + #VariableRegexApplyTo: "value" | "text" @cuetsy(kind="type") + // Sort variable options // Accepted values are: // `0`: No sorting @@ -696,6 +704,10 @@ lineage: schemas: [{ // Field options allow you to change how the data is displayed in your visualizations. fieldConfig?: #FieldConfigSource + + // When a panel is migrated from a previous version (Angular to React), this field is set to the original panel type. + // This is used to determine the original panel type when migrating to a new version so the plugin migration can be applied. + autoMigrateFrom?: string } @cuetsy(kind="interface") @grafana(TSVeneer="type") @grafanamaturity(NeedsExpertReview) // The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. diff --git a/package.json b/package.json index e9ce0640360..72a8f638cb6 100644 --- a/package.json +++ b/package.json @@ -26,10 +26,10 @@ "e2e:enterprise": "./e2e/start-and-run-suite enterprise", "e2e:enterprise:dev": "./e2e/start-and-run-suite enterprise dev", "e2e:enterprise:debug": "./e2e/start-and-run-suite enterprise debug", - "e2e:playwright": "yarn playwright test --grep-invert @cloud-plugins", - "e2e:playwright:cloud-plugins": "yarn playwright test --grep @cloud-plugins", - "e2e:playwright:storybook": "yarn playwright test -c playwright.storybook.config.ts", - "e2e:acceptance": "yarn playwright test --grep @acceptance", + "e2e:playwright": "NODE_OPTIONS='-C @grafana-app/source' yarn playwright test --grep-invert @cloud-plugins", + "e2e:playwright:cloud-plugins": "NODE_OPTIONS='-C @grafana-app/source' yarn playwright test --grep @cloud-plugins", + "e2e:playwright:storybook": "NODE_OPTIONS='-C @grafana-app/source' yarn playwright test -c playwright.storybook.config.ts", + "e2e:acceptance": "NODE_OPTIONS='-C @grafana-app/source' yarn playwright test --grep @acceptance", "e2e:storybook": "PORT=9001 ./e2e/run-suite storybook true", "e2e:plugin:build": "nx run-many -t build --projects='@test-plugins/*'", "e2e:plugin:build:dev": "nx run-many -t dev --projects='@test-plugins/*' --maxParallel=100", @@ -63,7 +63,7 @@ "storybook": "yarn workspace @grafana/ui storybook --ci", "storybook:build": "yarn workspace @grafana/ui storybook:build", "themes-schema": "typescript-json-schema ./tsconfig.json NewThemeOptions --include 'packages/grafana-data/src/themes/createTheme.ts' --out public/app/features/theme-playground/schema.generated.json", - "themes-generate": "yarn themes-schema && esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --platform=node --tsconfig=./scripts/cli/tsconfig.json | node", + "themes-generate": "yarn themes-schema && esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --conditions=@grafana-app/source --platform=node --tsconfig=./scripts/cli/tsconfig.json | node", "themes:usage": "eslint . --ignore-pattern '*.test.ts*' --ignore-pattern '*.spec.ts*' --cache --plugin '@grafana' --rule '{ @grafana/theme-token-usage: \"error\" }'", "typecheck": "tsc --noEmit && yarn run packages:typecheck", "plugins:build-bundled": "echo 'bundled plugins are no longer supported'", @@ -92,7 +92,7 @@ "@emotion/eslint-plugin": "11.12.0", "@grafana/eslint-config": "8.2.0", "@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules", - "@grafana/plugin-e2e": "^3.0.3", + "@grafana/plugin-e2e": "^3.1.0", "@grafana/test-utils": "workspace:*", "@manypkg/get-packages": "^3.0.0", "@npmcli/package-json": "^6.0.0", @@ -124,7 +124,6 @@ "@types/eslint": "9.6.1", "@types/eslint-scope": "^8.0.0", "@types/file-saver": "2.0.7", - "@types/glob": "^9.0.0", "@types/google.analytics": "^0.0.46", "@types/gtag.js": "^0.0.20", "@types/history": "4.7.11", @@ -290,14 +289,14 @@ "@grafana/google-sdk": "0.3.5", "@grafana/i18n": "workspace:*", "@grafana/lezer-logql": "0.2.9", - "@grafana/llm": "0.22.1", + "@grafana/llm": "1.0.1", "@grafana/monaco-logql": "^0.0.8", "@grafana/o11y-ds-frontend": "workspace:*", "@grafana/plugin-ui": "^0.11.1", "@grafana/prometheus": "workspace:*", "@grafana/runtime": "workspace:*", - "@grafana/scenes": "6.47.1", - "@grafana/scenes-react": "6.47.1", + "@grafana/scenes": "v6.52.1", + "@grafana/scenes-react": "v6.52.1", "@grafana/schema": "workspace:*", "@grafana/sql": "workspace:*", "@grafana/ui": "workspace:*", @@ -348,6 +347,7 @@ "date-fns": "4.1.0", "debounce-promise": "3.1.2", "diff": "^8.0.0", + "downsample": "1.4.0", "fast-deep-equal": "^3.1.3", "fast-json-patch": "3.1.1", "file-saver": "2.0.5", @@ -460,7 +460,9 @@ "gitconfiglocal": "2.1.0", "tmp@npm:^0.0.33": "~0.2.1", "js-yaml@npm:4.1.0": "^4.1.0", - "js-yaml@npm:=4.1.0": "^4.1.0" + "js-yaml@npm:=4.1.0": "^4.1.0", + "nodemailer": "7.0.11", + "@storybook/core@npm:8.6.15": "patch:@storybook/core@npm%3A8.6.15#~/.yarn/patches/@storybook-core-npm-8.6.15-a468a35170.patch" }, "workspaces": { "packages": [ diff --git a/packages/README.md b/packages/README.md index b42f7082c5c..3fa0dceebc7 100644 --- a/packages/README.md +++ b/packages/README.md @@ -2,13 +2,32 @@ ## Exporting code conventions -`@grafana/ui`, `@grafana/data` and `@grafana/runtime` makes use of `exports` in package.json to define three entrypoints that Grafana core and Grafana plugins can access. Before exposing anything in these packages please consider the table below to better understand the use case of each export. +All the `@grafana` packages in this repo (except `@grafana/schema`) make use of `exports` in package.json to define entrypoints that Grafana core and Grafana plugins can access. Exports can also be used to restrict access to internal files in packages. -| Export Name | Import Path | Description | Available to Grafana | Available to plugins | -| ------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -------------------- | -| `./` | `@grafana/ui` | The public API entrypoint. If the code is stable and you want to share it everywhere, this is the place to export it. | ✅ | ✅ | -| `./unstable` | `@grafana/ui/unstable` | The public API entrypoint for all experimental code. If you want to iterate and test code from Grafana and plugins, this is the place to export it. | ✅ | ✅ | -| `./internal` | `@grafana/ui/internal` | The private API entrypoint for internal code shared with Grafana. If you need to import code in Grafana but don't want to expose it to plugins, this is the place to export it. | ✅ | ❌ | +Package authors are free to create as many exports as they like but should consider the following points: + +1. Resolution of source code within this repo is handled by the [customCondition](https://www.typescriptlang.org/tsconfig/#customConditions) `@grafana-app/source`. This allows the frontend tooling in this repo to resolve to the source code preventing the need to build all the packages up front. When adding exports it is important to add an entry for the custom condition as the first item. All other entries should point to the built, bundled files. For example: + + ```json + "exports": { + ".": { + "@grafana-app/source": "./src/index.ts", + "types": "./dist/types/index.d.ts", + "import": "./dist/esm/index.mjs", + "require": "./dist/cjs/index.cjs" + } + } + ``` + +2. If you add exports to your package you must export the `package.json` file. + +3. Before exposing anything in these packages please consider the table below to better understand the conventions we have put in place for most of the packages in this repository. + +| Export Name | Import Path | Description | Available to Grafana | Available to plugins | +| ------------ | ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -------------------- | +| `./` | `@grafana/ui` | The public API entrypoint. If the code is stable and you want to share it everywhere, this is the place to export it. | ✅ | ✅ | +| `./unstable` | `@grafana/ui/unstable` | The public API entrypoint for all experimental code. If you want to iterate and test code from Grafana and plugins, this is the place to export it. | ✅ | ✅ | +| `./internal` | `@grafana/ui/internal` | The private API entrypoint for internal code shared with Grafana. If you want to co-locate code in a package with it's public API but only want the Grafana application to access it, this is the place to export it. | ✅ | ❌ | ## Versioning diff --git a/packages/grafana-alerting/package.json b/packages/grafana-alerting/package.json index 1c3ab2bf9b4..fa0ee6e5168 100644 --- a/packages/grafana-alerting/package.json +++ b/packages/grafana-alerting/package.json @@ -17,32 +17,34 @@ "url": "http://github.com/grafana/grafana.git", "directory": "packages/grafana-alerting" }, - "main": "src/index.ts", - "types": "src/index.ts", - "module": "src/index.ts", + "main": "./dist/cjs/index.cjs", + "module": "./dist/esm/index.mjs", + "types": "./dist/types/index.d.ts", "exports": { "./package.json": "./package.json", ".": { - "import": "./src/index.ts", - "require": "./src/index.ts" - }, - "./internal": { - "import": "./src/internal.ts", - "require": "./src/internal.ts" + "@grafana-app/source": "./src/index.ts", + "types": "./dist/types/index.d.ts", + "import": "./dist/esm/index.mjs", + "require": "./dist/cjs/index.cjs" }, "./unstable": { - "import": "./src/unstable.ts", - "require": "./src/unstable.ts" + "@grafana-app/source": "./src/unstable.ts", + "types": "./dist/types/unstable.d.ts", + "import": "./dist/esm/unstable.mjs", + "require": "./dist/cjs/unstable.cjs" + }, + "./internal": { + "@grafana-app/source": "./src/internal.ts" }, "./testing": { - "import": "./src/testing.ts", - "require": "./src/testing.ts" + "@grafana-app/source": "./src/testing.ts", + "types": "./dist/types/testing.d.ts", + "import": "./dist/esm/testing.mjs", + "require": "./dist/cjs/testing.cjs" } }, "publishConfig": { - "main": "./dist/cjs/index.cjs", - "module": "./dist/esm/index.mjs", - "types": "./dist/types/index.d.ts", "access": "public" }, "files": [ @@ -56,14 +58,12 @@ "bundle": "rollup -c rollup.config.ts --configPlugin esbuild", "clean": "rimraf ./dist ./compiled ./unstable ./testing ./package.tgz", "typecheck": "tsc --emitDeclarationOnly false --noEmit", - "codegen": "rtk-query-codegen-openapi ./scripts/codegen.ts", - "prepack": "cp package.json package.json.bak && ALIAS_PACKAGE_NAME=testing,unstable node ../../scripts/prepare-npm-package.js", - "postpack": "mv package.json.bak package.json && rimraf ./unstable ./testing", + "prepack": "cp package.json package.json.bak && node ../../scripts/prepare-npm-package.js", + "postpack": "mv package.json.bak package.json", "i18n-extract": "i18next-cli extract --sync-primary" }, "devDependencies": { "@grafana/test-utils": "workspace:*", - "@rtk-query/codegen-openapi": "^2.0.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@testing-library/user-event": "^14.6.1", @@ -94,8 +94,9 @@ "dependencies": { "@emotion/css": "11.13.5", "@faker-js/faker": "^9.8.0", + "@grafana/api-clients": "12.4.0-pre", "@grafana/i18n": "12.4.0-pre", - "@reduxjs/toolkit": "^2.9.0", + "@reduxjs/toolkit": "2.10.1", "fishery": "^2.3.1", "lodash": "^4.17.21", "tinycolor2": "^1.6.0" diff --git a/packages/grafana-alerting/rollup.config.ts b/packages/grafana-alerting/rollup.config.ts index f8f41e3ad2c..43914b47b70 100644 --- a/packages/grafana-alerting/rollup.config.ts +++ b/packages/grafana-alerting/rollup.config.ts @@ -9,19 +9,19 @@ export default [ { input: entryPoint, plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-alerting')], + output: [cjsOutput(pkg, 'grafana-alerting'), esmOutput(pkg, 'grafana-alerting')], treeshake: false, }, { input: 'src/unstable.ts', plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-alerting')], + output: [cjsOutput(pkg, 'grafana-alerting'), esmOutput(pkg, 'grafana-alerting')], treeshake: false, }, { input: 'src/testing.ts', plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-alerting')], + output: [cjsOutput(pkg, 'grafana-alerting'), esmOutput(pkg, 'grafana-alerting')], treeshake: false, }, ]; diff --git a/packages/grafana-alerting/scripts/README.md b/packages/grafana-alerting/scripts/README.md deleted file mode 100644 index 32730a22a13..00000000000 --- a/packages/grafana-alerting/scripts/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Re-generate the clients - -⚠️ This guide assumes the Backend definitions have been updated in `apps/alerting`. - -## Re-create OpenAPI specification - -Start with re-generating the OpenAPI snapshots by running the test in `pkg/tests/apis/openapi_test.go`. - -This will output the OpenAPI JSON spec file(s) in `pkg/tests/apis/openapi_snapshots`. - -## Process OpenAPI specifications - -Next up run the post-processing of the snapshots with `yarn run process-specs`, this will copy processed specifications to `./data/openapi/`. - -## Generate RTKQ files - -These files are built using the `yarn run codegen` command, make sure to run that in the Grafana Alerting package working directory. - -`yarn --cwd ./packages/grafana-alerting run codegen`. - -API clients will be written to `src/grafana/api//api.gen.ts`. - -Make sure to create a versioned API client for each API version – see `src/grafana/api/v0alpha1/api.ts` as an example. diff --git a/packages/grafana-alerting/scripts/codegen.ts b/packages/grafana-alerting/scripts/codegen.ts deleted file mode 100644 index 59c9a7e5cb8..00000000000 --- a/packages/grafana-alerting/scripts/codegen.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * This script will generate TypeScript type definitions and a RTKQ clients for the alerting k8s APIs. - * - * Run `yarn run codegen` from the "grafana-alerting" package to invoke this script. - * - * API clients will be placed in "src/grafana/api//api.gen.ts" - */ -import type { ConfigFile } from '@rtk-query/codegen-openapi'; - -// ℹ️ append API groups and versions here to generate additional API clients -const SPECS = [ - ['notifications.alerting.grafana.app', ['v0alpha1']], - ['rules.alerting.grafana.app', ['v0alpha1']], - // keep this in Grafana Enterprise - // ['alertenrichment.grafana.app', ['v1beta1']], -] as const; - -type OutputFile = Omit; -type OutputFiles = Record; - -const outputFiles = SPECS.reduce((groupAcc, [group, versions]) => { - return versions.reduce((versionAcc, version) => { - // Create a unique export name based on the group - const groupName = group.split('.')[0]; // e.g., 'notifications', 'rules', 'alertenrichment' - const exportName = `${groupName}API`; - - // ℹ️ these snapshots are generated by running "go test pkg/tests/apis/openapi_test.go" and "scripts/process-specs.ts", - // see the README in the "openapi_snapshots" directory - const schemaFile = `../../../data/openapi/${group}-${version}.json`; - - // ℹ️ make sure there is a API file in each versioned directory - const apiFile = `../src/grafana/api/${groupName}/${version}/api.ts`; - - // output each api client into a versioned directory with group-specific naming - const outputPath = `../src/grafana/api/${groupName}/${version}/${groupName}.api.gen.ts`; - - versionAcc[outputPath] = { - exportName, - schemaFile, - apiFile, - tag: true, // generate tags for cache invalidation - } satisfies OutputFile; - - return versionAcc; - }, groupAcc); -}, {}); - -export default { - // these are intentionally empty but will be set for each versioned config file - exportName: '', - schemaFile: '', - apiFile: '', - - outputFiles, -} satisfies ConfigFile; diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/api.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/api.ts deleted file mode 100644 index 5b45157954f..00000000000 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/api.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; - -import { getAPIBaseURL, getAPIReducerPath } from '../../util'; - -import { GROUP, VERSION } from './const'; - -const baseUrl = getAPIBaseURL(GROUP, VERSION); -const reducerPath = getAPIReducerPath(GROUP, VERSION); - -export const api = createApi({ - reducerPath, - baseQuery: fetchBaseQuery({ - // Set URL correctly so MSW can intercept requests - // https://mswjs.io/docs/runbook#rtk-query-requests-are-not-intercepted - baseUrl: new URL(baseUrl, globalThis.location.origin).href, - }), - endpoints: () => ({}), -}); diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/const.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/const.ts deleted file mode 100644 index a196bb9516e..00000000000 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/const.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const VERSION = 'v0alpha1' as const; -export const GROUP = 'notifications.alerting.grafana.app' as const; diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/fakes/Receivers.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/fakes/Receivers.ts index fbd88a5972d..693e2a05f30 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/fakes/Receivers.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/fakes/Receivers.ts @@ -1,8 +1,9 @@ import { faker } from '@faker-js/faker'; import { Factory } from 'fishery'; +import { API_GROUP, API_VERSION } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { DEFAULT_NAMESPACE, generateResourceVersion, generateTitle, generateUID } from '../../../../../mocks/util'; -import { GROUP, VERSION } from '../../const'; import { ContactPoint, ContactPointMetadataAnnotations, @@ -14,7 +15,7 @@ import { AlertingEntityMetadataAnnotationsFactory } from './common'; export const ListReceiverApiResponseFactory = Factory.define(() => ({ kind: 'ReceiverList', - apiVersion: `${GROUP}/${VERSION}`, + apiVersion: `${API_GROUP}/${API_VERSION}`, metadata: { resourceVersion: generateResourceVersion(), }, @@ -26,7 +27,7 @@ export const ContactPointFactory = Factory.define(() => { return { kind: 'Receiver', - apiVersion: `${GROUP}/${VERSION}`, + apiVersion: `${API_GROUP}/${API_VERSION}`, metadata: { name: btoa(title), namespace: DEFAULT_NAMESPACE, diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/createReceiverHandler.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/createReceiverHandler.ts index 2c21893b6d3..7502d4da000 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/createReceiverHandler.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/createReceiverHandler.ts @@ -1,13 +1,17 @@ import { HttpResponse, http } from 'msw'; +import { + API_GROUP, + API_VERSION, + CreateReceiverApiResponse, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { getAPIBaseURLForMocks } from '../../../../../../mocks/util'; -import { CreateReceiverApiResponse } from '../../../../v0alpha1/notifications.api.gen'; -import { GROUP, VERSION } from '../../../const'; export function createReceiverHandler( data: CreateReceiverApiResponse | ((info: Parameters[1]>[0]) => Response) ) { - return http.post(getAPIBaseURLForMocks(GROUP, VERSION, '/receivers'), function handler(info) { + return http.post(getAPIBaseURLForMocks(API_GROUP, API_VERSION, '/receivers'), function handler(info) { if (typeof data === 'function') { return data(info); } diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deleteReceiverHandler.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deleteReceiverHandler.ts index d3ff5c660f8..fc859d30043 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deleteReceiverHandler.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deleteReceiverHandler.ts @@ -1,13 +1,17 @@ import { HttpResponse, http } from 'msw'; +import { + API_GROUP, + API_VERSION, + DeleteReceiverApiResponse, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { getAPIBaseURLForMocks } from '../../../../../../mocks/util'; -import { DeleteReceiverApiResponse } from '../../../../v0alpha1/notifications.api.gen'; -import { GROUP, VERSION } from '../../../const'; export function deleteReceiverHandler( data: DeleteReceiverApiResponse | ((info: Parameters[1]>[0]) => Response) ) { - return http.delete(getAPIBaseURLForMocks(GROUP, VERSION, '/receivers/:name'), function handler(info) { + return http.delete(getAPIBaseURLForMocks(API_GROUP, API_VERSION, '/receivers/:name'), function handler(info) { if (typeof data === 'function') { return data(info); } diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deletecollectionReceiverHandler.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deletecollectionReceiverHandler.ts index f3871112e66..27f68e67834 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deletecollectionReceiverHandler.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/deletecollectionReceiverHandler.ts @@ -1,13 +1,17 @@ import { HttpResponse, http } from 'msw'; +import { + API_GROUP, + API_VERSION, + DeletecollectionReceiverApiResponse, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { getAPIBaseURLForMocks } from '../../../../../../mocks/util'; -import { DeletecollectionReceiverApiResponse } from '../../../../v0alpha1/notifications.api.gen'; -import { GROUP, VERSION } from '../../../const'; export function deletecollectionReceiverHandler( data: DeletecollectionReceiverApiResponse | ((info: Parameters[1]>[0]) => Response) ) { - return http.delete(getAPIBaseURLForMocks(GROUP, VERSION, '/receivers'), function handler(info) { + return http.delete(getAPIBaseURLForMocks(API_GROUP, API_VERSION, '/receivers'), function handler(info) { if (typeof data === 'function') { return data(info); } diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/getReceiverHandler.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/getReceiverHandler.ts index d90d1fbecba..c7e533d47dc 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/getReceiverHandler.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/getReceiverHandler.ts @@ -1,13 +1,17 @@ import { HttpResponse, http } from 'msw'; +import { + API_GROUP, + API_VERSION, + GetReceiverApiResponse, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { getAPIBaseURLForMocks } from '../../../../../../mocks/util'; -import { GetReceiverApiResponse } from '../../../../v0alpha1/notifications.api.gen'; -import { GROUP, VERSION } from '../../../const'; export function getReceiverHandler( data: GetReceiverApiResponse | ((info: Parameters[1]>[0]) => Response) ) { - return http.get(getAPIBaseURLForMocks(GROUP, VERSION, '/receivers/:name'), function handler(info) { + return http.get(getAPIBaseURLForMocks(API_GROUP, API_VERSION, '/receivers/:name'), function handler(info) { if (typeof data === 'function') { return data(info); } diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/listReceiverHandler.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/listReceiverHandler.ts index fde49565388..b6f577bcca5 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/listReceiverHandler.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/listReceiverHandler.ts @@ -1,13 +1,14 @@ import { HttpResponse, http } from 'msw'; +import { API_GROUP, API_VERSION } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { getAPIBaseURLForMocks } from '../../../../../../mocks/util'; -import { GROUP, VERSION } from '../../../const'; import { EnhancedListReceiverApiResponse } from '../../../types'; export function listReceiverHandler( data: EnhancedListReceiverApiResponse | ((info: Parameters[1]>[0]) => Response) ) { - return http.get(getAPIBaseURLForMocks(GROUP, VERSION, '/receivers'), function handler(info) { + return http.get(getAPIBaseURLForMocks(API_GROUP, API_VERSION, '/receivers'), function handler(info) { if (typeof data === 'function') { return data(info); } diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/replaceReceiverHandler.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/replaceReceiverHandler.ts index c054de71882..1ed5bb7b50b 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/replaceReceiverHandler.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/replaceReceiverHandler.ts @@ -1,13 +1,17 @@ import { HttpResponse, http } from 'msw'; +import { + API_GROUP, + API_VERSION, + ReplaceReceiverApiResponse, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { getAPIBaseURLForMocks } from '../../../../../../mocks/util'; -import { ReplaceReceiverApiResponse } from '../../../../v0alpha1/notifications.api.gen'; -import { GROUP, VERSION } from '../../../const'; export function replaceReceiverHandler( data: ReplaceReceiverApiResponse | ((info: Parameters[1]>[0]) => Response) ) { - return http.put(getAPIBaseURLForMocks(GROUP, VERSION, '/receivers/:name'), function handler(info) { + return http.put(getAPIBaseURLForMocks(API_GROUP, API_VERSION, '/receivers/:name'), function handler(info) { if (typeof data === 'function') { return data(info); } diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/updateReceiverHandler.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/updateReceiverHandler.ts index ce8498331cd..3b2c7536ec2 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/updateReceiverHandler.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers/ReceiverHandlers/updateReceiverHandler.ts @@ -1,13 +1,17 @@ import { HttpResponse, http } from 'msw'; +import { + API_GROUP, + API_VERSION, + UpdateReceiverApiResponse, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { getAPIBaseURLForMocks } from '../../../../../../mocks/util'; -import { UpdateReceiverApiResponse } from '../../../../v0alpha1/notifications.api.gen'; -import { GROUP, VERSION } from '../../../const'; export function updateReceiverHandler( data: UpdateReceiverApiResponse | ((info: Parameters[1]>[0]) => Response) ) { - return http.patch(getAPIBaseURLForMocks(GROUP, VERSION, '/receivers/:name'), function handler(info) { + return http.patch(getAPIBaseURLForMocks(API_GROUP, API_VERSION, '/receivers/:name'), function handler(info) { if (typeof data === 'function') { return data(info); } diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/types.ts b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/types.ts index 1212fc74b92..b5913c3ab38 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/types.ts +++ b/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/types.ts @@ -3,7 +3,11 @@ */ import { MergeDeep, MergeExclusive, OverrideProperties } from 'type-fest'; -import type { ListReceiverApiResponse, Receiver, ReceiverIntegration } from './notifications.api.gen'; +import type { + ListReceiverApiResponse, + Receiver, + ReceiverIntegration, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; type GenericIntegration = OverrideProperties< ReceiverIntegration, diff --git a/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/api.ts b/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/api.ts deleted file mode 100644 index 5b45157954f..00000000000 --- a/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/api.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; - -import { getAPIBaseURL, getAPIReducerPath } from '../../util'; - -import { GROUP, VERSION } from './const'; - -const baseUrl = getAPIBaseURL(GROUP, VERSION); -const reducerPath = getAPIReducerPath(GROUP, VERSION); - -export const api = createApi({ - reducerPath, - baseQuery: fetchBaseQuery({ - // Set URL correctly so MSW can intercept requests - // https://mswjs.io/docs/runbook#rtk-query-requests-are-not-intercepted - baseUrl: new URL(baseUrl, globalThis.location.origin).href, - }), - endpoints: () => ({}), -}); diff --git a/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/const.ts b/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/const.ts deleted file mode 100644 index 823560db3fb..00000000000 --- a/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/const.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const VERSION = 'v0alpha1' as const; -export const GROUP = 'rules.alerting.grafana.app' as const; diff --git a/packages/grafana-alerting/src/grafana/contactPoints/hooks/v0alpha1/useContactPoints.tsx b/packages/grafana-alerting/src/grafana/contactPoints/hooks/v0alpha1/useContactPoints.tsx index 7b6ec11f2b2..60a661ac749 100644 --- a/packages/grafana-alerting/src/grafana/contactPoints/hooks/v0alpha1/useContactPoints.tsx +++ b/packages/grafana-alerting/src/grafana/contactPoints/hooks/v0alpha1/useContactPoints.tsx @@ -7,9 +7,10 @@ import { OverrideProperties } from 'type-fest'; import { CreateReceiverApiArg, - type ListReceiverApiArg, - notificationsAPI, -} from '../../../api/notifications/v0alpha1/notifications.api.gen'; + ListReceiverApiArg, + generatedAPI as notificationsAPIv0alpha1, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import type { ContactPoint, EnhancedListReceiverApiResponse } from '../../../api/notifications/v0alpha1/types'; // this is a workaround for the fact that the generated types are not narrow enough @@ -22,17 +23,17 @@ type ListContactPointsHookResult = TypedUseQueryHookResult< // Type for the options that can be passed to the hook // Based on the pattern used for mutation options in this file type ListContactPointsQueryArgs = Parameters< - typeof notificationsAPI.endpoints.listReceiver.useQuery + typeof notificationsAPIv0alpha1.endpoints.listReceiver.useQuery >[0]; type ListContactPointsQueryOptions = Parameters< - typeof notificationsAPI.endpoints.listReceiver.useQuery + typeof notificationsAPIv0alpha1.endpoints.listReceiver.useQuery >[1]; /** * useListContactPoints is a hook that fetches a list of contact points * - * This function wraps the notificationsAPI.useListReceiverQuery with proper typing + * This function wraps the notificationsAPIv0alpha1.useListReceiverQuery with proper typing * to ensure that the returned ContactPoints are correctly typed in the data.items array. * * It automatically uses the configured namespace for the query. @@ -43,8 +44,8 @@ type ListContactPointsQueryOptions = Parameters< export function useListContactPoints( queryArgs: ListContactPointsQueryArgs = {}, queryOptions: ListContactPointsQueryOptions = {} -) { - return notificationsAPI.useListReceiverQuery(queryArgs, queryOptions); +): ListContactPointsHookResult { + return notificationsAPIv0alpha1.useListReceiverQuery(queryArgs, queryOptions); } // type narrowing mutations requires us to define a few helper types @@ -60,7 +61,7 @@ type CreateContactPointMutation = TypedUseMutationResult< >; type UseCreateContactPointOptions = Parameters< - typeof notificationsAPI.endpoints.createReceiver.useMutation + typeof notificationsAPIv0alpha1.endpoints.createReceiver.useMutation >[0]; /** @@ -69,8 +70,16 @@ type UseCreateContactPointOptions = Parameters< * This function wraps the notificationsAPI.useCreateReceiverMutation with proper typing * to ensure that the payload supports type narrowing. */ -export function useCreateContactPoint(options?: UseCreateContactPointOptions) { - const [updateFn, result] = notificationsAPI.endpoints.createReceiver.useMutation(options); +export function useCreateContactPoint( + options?: UseCreateContactPointOptions +): readonly [ + ( + args: CreateContactPointArgs + ) => ReturnType[0]>, + ReturnType>[1], +] { + const [updateFn, result] = + notificationsAPIv0alpha1.endpoints.createReceiver.useMutation(options); const typedUpdateFn = (args: CreateContactPointArgs) => { // @ts-expect-error this one is just impossible for me to figure out diff --git a/packages/grafana-alerting/src/grafana/contactPoints/utils.ts b/packages/grafana-alerting/src/grafana/contactPoints/utils.ts index ac4242bd1b1..e6748c657ff 100644 --- a/packages/grafana-alerting/src/grafana/contactPoints/utils.ts +++ b/packages/grafana-alerting/src/grafana/contactPoints/utils.ts @@ -1,6 +1,7 @@ import { countBy, isEmpty } from 'lodash'; -import { Receiver } from '../api/notifications/v0alpha1/notifications.api.gen'; +import { Receiver } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { ContactPoint } from '../api/notifications/v0alpha1/types'; /** diff --git a/packages/grafana-alerting/src/grafana/matchers/types.ts b/packages/grafana-alerting/src/grafana/matchers/types.ts index 3cf3103fd1c..f2d20ace7e9 100644 --- a/packages/grafana-alerting/src/grafana/matchers/types.ts +++ b/packages/grafana-alerting/src/grafana/matchers/types.ts @@ -1,4 +1,4 @@ -import { RoutingTreeMatcher } from '../api/notifications/v0alpha1/notifications.api.gen'; +import { RoutingTreeMatcher } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; export type Label = [string, string]; diff --git a/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.test.ts b/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.test.ts index dc650db546b..655b4571309 100644 --- a/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.test.ts +++ b/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.test.ts @@ -1,6 +1,6 @@ -import { VERSION } from '../../api/notifications/v0alpha1/const'; +import { API_VERSION, RoutingTree } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { LabelMatcherFactory, RouteFactory } from '../../api/notifications/v0alpha1/mocks/fakes/Routes'; -import { RoutingTree } from '../../api/notifications/v0alpha1/notifications.api.gen'; import { Label } from '../../matchers/types'; import { matchInstancesToRouteTrees } from './useMatchPolicies'; @@ -16,7 +16,7 @@ describe('matchInstancesToRouteTrees', () => { const trees: RoutingTree[] = [ { kind: 'RoutingTree', - apiVersion: VERSION, + apiVersion: API_VERSION, metadata: { name: treeName }, spec: { defaults: { @@ -24,7 +24,6 @@ describe('matchInstancesToRouteTrees', () => { }, routes: [route], }, - status: {}, }, ]; @@ -51,7 +50,7 @@ describe('matchInstancesToRouteTrees', () => { const trees: RoutingTree[] = [ { kind: 'RoutingTree', - apiVersion: VERSION, + apiVersion: API_VERSION, metadata: { name: treeName }, spec: { defaults: { @@ -59,7 +58,6 @@ describe('matchInstancesToRouteTrees', () => { }, routes: [route], }, - status: {}, }, ]; diff --git a/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.ts b/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.ts index d23efaae967..305671601f7 100644 --- a/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.ts +++ b/packages/grafana-alerting/src/grafana/notificationPolicies/hooks/useMatchPolicies.ts @@ -1,6 +1,10 @@ import { useCallback } from 'react'; -import { RoutingTree, notificationsAPI } from '../../api/notifications/v0alpha1/notifications.api.gen'; +import { + RoutingTree, + generatedAPI as notificationsAPIv0alpha1, +} from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { Label } from '../../matchers/types'; import { USER_DEFINED_TREE_NAME } from '../consts'; import { Route, RouteWithID } from '../types'; @@ -24,6 +28,11 @@ export type InstanceMatchResult = { matchedRoutes: RouteMatch[]; }; +interface UseMatchInstancesToRouteTreesReturnType + extends ReturnType { + matchInstancesToRouteTrees: (instances: Label[][]) => InstanceMatchResult[]; +} + /** * React hook that finds notification policy routes in all routing trees that match the provided set of alert instances. * @@ -35,8 +44,8 @@ export type InstanceMatchResult = { * @returns An object containing a `matchInstancesToRoutingTrees` function that takes alert instances * and returns an array of InstanceMatchResult objects, each containing the matched routes and matching details */ -export function useMatchInstancesToRouteTrees() { - const { data, ...rest } = notificationsAPI.endpoints.listRoutingTree.useQuery( +export function useMatchInstancesToRouteTrees(): UseMatchInstancesToRouteTreesReturnType { + const { data, ...rest } = notificationsAPIv0alpha1.endpoints.listRoutingTree.useQuery( {}, { refetchOnFocus: true, diff --git a/packages/grafana-alerting/src/grafana/notificationPolicies/types.ts b/packages/grafana-alerting/src/grafana/notificationPolicies/types.ts index 56465daf613..84f0e07d3b7 100644 --- a/packages/grafana-alerting/src/grafana/notificationPolicies/types.ts +++ b/packages/grafana-alerting/src/grafana/notificationPolicies/types.ts @@ -1,6 +1,7 @@ import { OverrideProperties } from 'type-fest'; -import { RoutingTreeRoute } from '../api/notifications/v0alpha1/notifications.api.gen'; +import { RoutingTreeRoute } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { LabelMatcher } from '../matchers/types'; // type-narrow the route tree diff --git a/packages/grafana-alerting/src/grafana/notificationPolicies/utils.ts b/packages/grafana-alerting/src/grafana/notificationPolicies/utils.ts index 1fc7608a76f..6f7fb7d2ade 100644 --- a/packages/grafana-alerting/src/grafana/notificationPolicies/utils.ts +++ b/packages/grafana-alerting/src/grafana/notificationPolicies/utils.ts @@ -1,6 +1,7 @@ import { groupBy, isArray, pick, reduce, uniqueId } from 'lodash'; -import { RoutingTree, RoutingTreeRoute } from '../api/notifications/v0alpha1/notifications.api.gen'; +import { RoutingTree, RoutingTreeRoute } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; + import { Label } from '../matchers/types'; import { LabelMatchDetails, matchLabels } from '../matchers/utils'; diff --git a/packages/grafana-alerting/src/unstable.ts b/packages/grafana-alerting/src/unstable.ts index e033b55437c..15bce11bebf 100644 --- a/packages/grafana-alerting/src/unstable.ts +++ b/packages/grafana-alerting/src/unstable.ts @@ -19,5 +19,5 @@ export { type LabelMatcher, type Label } from './grafana/matchers/types'; export { matchLabelsSet, matchLabels, isLabelMatch, type LabelMatchDetails } from './grafana/matchers/utils'; // API endpoints -export { notificationsAPI as notificationsAPIv0alpha1 } from './grafana/api/notifications/v0alpha1/notifications.api.gen'; -export { rulesAPI as rulesAPIv0alpha1 } from './grafana/api/rules/v0alpha1/rules.api.gen'; +export { generatedAPI as notificationsAPIv0alpha1 } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; +export { generatedAPI as rulesAPIv0alpha1 } from '@grafana/api-clients/rtkq/rules.alerting/v0alpha1'; diff --git a/packages/grafana-alerting/tests/provider.tsx b/packages/grafana-alerting/tests/provider.tsx index b3caa8679b2..7a3ac8bc241 100644 --- a/packages/grafana-alerting/tests/provider.tsx +++ b/packages/grafana-alerting/tests/provider.tsx @@ -2,13 +2,25 @@ import { configureStore } from '@reduxjs/toolkit'; import { useEffect } from 'react'; import { Provider } from 'react-redux'; -import { notificationsAPIv0alpha1 } from '../src/unstable'; +import { MockBackendSrv } from '@grafana/api-clients'; +import { generatedAPI as notificationsAPIv0alpha1 } from '@grafana/api-clients/rtkq/notifications.alerting/v0alpha1'; +import { generatedAPI as rulesAPIv0alpha1 } from '@grafana/api-clients/rtkq/rules.alerting/v0alpha1'; +import { setBackendSrv } from '@grafana/runtime'; + +// Initialize BackendSrv for tests - this allows RTKQ to make HTTP requests +// The actual HTTP requests will be intercepted by MSW (setupMockServer) +// We only need to implement fetch() which is what RTKQ uses +// we could remove this once @grafana/api-client no longer uses the BackendSrv +// @ts-ignore +setBackendSrv(new MockBackendSrv()); // create an empty store -export const store = configureStore({ - middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(notificationsAPIv0alpha1.middleware), +export const store: ReturnType = configureStore({ + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat(notificationsAPIv0alpha1.middleware).concat(rulesAPIv0alpha1.middleware), reducer: { [notificationsAPIv0alpha1.reducerPath]: notificationsAPIv0alpha1.reducer, + [rulesAPIv0alpha1.reducerPath]: rulesAPIv0alpha1.reducer, }, }); diff --git a/packages/grafana-alerting/tests/test-utils.tsx b/packages/grafana-alerting/tests/test-utils.tsx index e0f0e12ac9c..5c7de34c9c3 100644 --- a/packages/grafana-alerting/tests/test-utils.tsx +++ b/packages/grafana-alerting/tests/test-utils.tsx @@ -13,7 +13,14 @@ import '@testing-library/jest-dom'; * method which wraps the passed element in all of the necessary Providers, * so it can render correctly in the context of the application */ -const customRender = (ui: React.ReactNode, renderOptions: RenderOptions = {}) => { +const customRender = ( + ui: React.ReactNode, + renderOptions: RenderOptions = {} +): { + renderResult: ReturnType; + user: ReturnType; + store: typeof store; +} => { const user = userEvent.setup(); const Providers = renderOptions.wrapper || getDefaultWrapper(); diff --git a/packages/grafana-api-clients/package.json b/packages/grafana-api-clients/package.json index 2d976b3a890..f72eab55212 100644 --- a/packages/grafana-api-clients/package.json +++ b/packages/grafana-api-clients/package.json @@ -15,88 +15,139 @@ "url": "https://github.com/grafana/grafana.git", "directory": "packages/grafana-api-clients" }, - "main": "src/index.ts", - "module": "src/index.ts", - "types": "src/index.ts", + "main": "./dist/cjs/index.cjs", + "module": "./dist/esm/index.mjs", + "types": "./dist/types/index.d.ts", "exports": { "./package.json": "./package.json", ".": { - "import": "./src/index.ts", - "require": "./src/index.ts" + "@grafana-app/source": "./src/index.ts", + "types": "./dist/types/index.d.ts", + "import": "./dist/esm/index.mjs", + "require": "./dist/cjs/index.cjs" }, "./rtkq": { - "import": "./src/clients/rtkq/index.ts", - "require": "./src/clients/rtkq/index.ts" + "@grafana-app/source": "./src/clients/rtkq/index.ts", + "types": "./dist/types/clients/rtkq/index.d.ts", + "import": "./dist/esm/clients/rtkq/index.mjs", + "require": "./dist/cjs/clients/rtkq/index.cjs" }, "./rtkq/advisor/v0alpha1": { - "import": "./src/clients/rtkq/advisor/v0alpha1/index.ts", - "require": "./src/clients/rtkq/advisor/v0alpha1/index.ts" - }, - "./rtkq/correlations/v0alpha1": { - "import": "./src/clients/rtkq/correlations/v0alpha1/index.ts", - "require": "./src/clients/rtkq/correlations/v0alpha1/index.ts" - }, - "./rtkq/dashboard/v0alpha1": { - "import": "./src/clients/rtkq/dashboard/v0alpha1/index.ts", - "require": "./src/clients/rtkq/dashboard/v0alpha1/index.ts" - }, - "./rtkq/folder/v1beta1": { - "import": "./src/clients/rtkq/folder/v1beta1/index.ts", - "require": "./src/clients/rtkq/folder/v1beta1/index.ts" - }, - "./rtkq/iam/v0alpha1": { - "import": "./src/clients/rtkq/iam/v0alpha1/index.ts", - "require": "./src/clients/rtkq/iam/v0alpha1/index.ts" - }, - "./rtkq/legacy": { - "import": "./src/clients/rtkq/legacy/index.ts", - "require": "./src/clients/rtkq/legacy/index.ts" - }, - "./rtkq/legacy/migrate-to-cloud": { - "import": "./src/clients/rtkq/migrate-to-cloud/index.ts", - "require": "./src/clients/rtkq/migrate-to-cloud/index.ts" - }, - "./rtkq/legacy/preferences": { - "import": "./src/clients/rtkq/preferences/user/index.ts", - "require": "./src/clients/rtkq/preferences/user/index.ts" - }, - "./rtkq/legacy/user": { - "import": "./src/clients/rtkq/user/index.ts", - "require": "./src/clients/rtkq/user/index.ts" - }, - "./rtkq/playlist/v0alpha1": { - "import": "./src/clients/rtkq/playlist/v0alpha1/index.ts", - "require": "./src/clients/rtkq/playlist/v0alpha1/index.ts" - }, - "./rtkq/preferences/v1alpha1": { - "import": "./src/clients/rtkq/preferences/v1alpha1/index.ts", - "require": "./src/clients/rtkq/preferences/v1alpha1/index.ts" + "@grafana-app/source": "./src/clients/rtkq/advisor/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/advisor/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/advisor/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/advisor/v0alpha1/index.cjs" }, "./rtkq/collections/v1alpha1": { - "import": "./src/clients/rtkq/collections/v1alpha1/index.ts", - "require": "./src/clients/rtkq/collections/v1alpha1/index.ts" + "@grafana-app/source": "./src/clients/rtkq/collections/v1alpha1/index.ts", + "types": "./dist/types/clients/rtkq/collections/v1alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/collections/v1alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/collections/v1alpha1/index.cjs" + }, + "./rtkq/correlations/v0alpha1": { + "@grafana-app/source": "./src/clients/rtkq/correlations/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/correlations/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/correlations/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/correlations/v0alpha1/index.cjs" + }, + "./rtkq/dashboard/v0alpha1": { + "@grafana-app/source": "./src/clients/rtkq/dashboard/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/dashboard/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/dashboard/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/dashboard/v0alpha1/index.cjs" + }, + "./rtkq/folder/v1beta1": { + "@grafana-app/source": "./src/clients/rtkq/folder/v1beta1/index.ts", + "types": "./dist/types/clients/rtkq/folder/v1beta1/index.d.ts", + "import": "./dist/esm/clients/rtkq/folder/v1beta1/index.mjs", + "require": "./dist/cjs/clients/rtkq/folder/v1beta1/index.cjs" + }, + "./rtkq/iam/v0alpha1": { + "@grafana-app/source": "./src/clients/rtkq/iam/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/iam/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/iam/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/iam/v0alpha1/index.cjs" + }, + "./rtkq/legacy": { + "@grafana-app/source": "./src/clients/rtkq/legacy/index.ts", + "types": "./dist/types/clients/rtkq/legacy/index.d.ts", + "import": "./dist/esm/clients/rtkq/legacy/index.mjs", + "require": "./dist/cjs/clients/rtkq/legacy/index.cjs" + }, + "./rtkq/legacy/migrate-to-cloud": { + "@grafana-app/source": "./src/clients/rtkq/migrate-to-cloud/index.ts", + "types": "./dist/types/clients/rtkq/migrate-to-cloud/index.d.ts", + "import": "./dist/esm/clients/rtkq/migrate-to-cloud/index.mjs", + "require": "./dist/cjs/clients/rtkq/migrate-to-cloud/index.cjs" + }, + "./rtkq/legacy/preferences": { + "@grafana-app/source": "./src/clients/rtkq/preferences/user/index.ts", + "types": "./dist/types/clients/rtkq/preferences/user/index.d.ts", + "import": "./dist/esm/clients/rtkq/preferences/user/index.mjs", + "require": "./dist/cjs/clients/rtkq/preferences/user/index.cjs" + }, + "./rtkq/legacy/user": { + "@grafana-app/source": "./src/clients/rtkq/user/index.ts", + "types": "./dist/types/clients/rtkq/user/index.d.ts", + "import": "./dist/esm/clients/rtkq/user/index.mjs", + "require": "./dist/cjs/clients/rtkq/user/index.cjs" + }, + "./rtkq/playlist/v0alpha1": { + "@grafana-app/source": "./src/clients/rtkq/playlist/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/playlist/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/playlist/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/playlist/v0alpha1/index.cjs" + }, + "./rtkq/preferences/v1alpha1": { + "@grafana-app/source": "./src/clients/rtkq/preferences/v1alpha1/index.ts", + "types": "./dist/types/clients/rtkq/preferences/v1alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/preferences/v1alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/preferences/v1alpha1/index.cjs" }, "./rtkq/provisioning/v0alpha1": { - "import": "./src/clients/rtkq/provisioning/v0alpha1/index.ts", - "require": "./src/clients/rtkq/provisioning/v0alpha1/index.ts" + "@grafana-app/source": "./src/clients/rtkq/provisioning/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/provisioning/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/provisioning/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/provisioning/v0alpha1/index.cjs" }, "./rtkq/shorturl/v1beta1": { - "import": "./src/clients/rtkq/shorturl/v1beta1/index.ts", - "require": "./src/clients/rtkq/shorturl/v1beta1/index.ts" + "@grafana-app/source": "./src/clients/rtkq/shorturl/v1beta1/index.ts", + "types": "./dist/types/clients/rtkq/shorturl/v1beta1/index.d.ts", + "import": "./dist/esm/clients/rtkq/shorturl/v1beta1/index.mjs", + "require": "./dist/cjs/clients/rtkq/shorturl/v1beta1/index.cjs" + }, + "./rtkq/notifications.alerting/v0alpha1": { + "@grafana-app/source": "./src/clients/rtkq/notifications.alerting/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/notifications.alerting/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/notifications.alerting/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/notifications.alerting/v0alpha1/index.cjs" + }, + "./rtkq/rules.alerting/v0alpha1": { + "@grafana-app/source": "./src/clients/rtkq/rules.alerting/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/rules.alerting/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/rules.alerting/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/rules.alerting/v0alpha1/index.cjs" }, "./rtkq/historian.alerting/v0alpha1": { - "import": "./src/clients/rtkq/historian.alerting/v0alpha1/index.ts", - "require": "./src/clients/rtkq/historian.alerting/v0alpha1/index.ts" + "@grafana-app/source": "./src/clients/rtkq/historian.alerting/v0alpha1/index.ts", + "types": "./dist/types/clients/rtkq/historian.alerting/v0alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/historian.alerting/v0alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/historian.alerting/v0alpha1/index.cjs" }, "./rtkq/logsdrilldown/v1alpha1": { - "import": "./src/clients/rtkq/logsdrilldown/v1alpha1/index.ts", - "require": "./src/clients/rtkq/logsdrilldown/v1alpha1/index.ts" + "@grafana-app/source": "./src/clients/rtkq/logsdrilldown/v1alpha1/index.ts", + "types": "./dist/types/clients/rtkq/logsdrilldown/v1alpha1/index.d.ts", + "import": "./dist/esm/clients/rtkq/logsdrilldown/v1alpha1/index.mjs", + "require": "./dist/cjs/clients/rtkq/logsdrilldown/v1alpha1/index.cjs" + }, + "./rtkq/logsdrilldown/v1beta1": { + "@grafana-app/source": "./src/clients/rtkq/logsdrilldown/v1beta1/index.ts", + "types": "./dist/types/clients/rtkq/logsdrilldown/v1beta1/index.d.ts", + "import": "./dist/esm/clients/rtkq/logsdrilldown/v1beta1/index.mjs", + "require": "./dist/cjs/clients/rtkq/logsdrilldown/v1beta1/index.cjs" } }, "publishConfig": { - "main": "./dist/cjs/index.cjs", - "module": "./dist/esm/index.mjs", - "types": "./dist/types/index.d.ts", "access": "public" }, "files": [ @@ -125,7 +176,7 @@ }, "peerDependencies": { "@grafana/runtime": ">=11.6 <= 12.x", - "@reduxjs/toolkit": "^2.8.0", + "@reduxjs/toolkit": "^2.10.0", "rxjs": "7.8.2" } } diff --git a/packages/grafana-api-clients/rollup.config.ts b/packages/grafana-api-clients/rollup.config.ts index b36d59278fc..976a0c000fa 100644 --- a/packages/grafana-api-clients/rollup.config.ts +++ b/packages/grafana-api-clients/rollup.config.ts @@ -5,35 +5,17 @@ import { cjsOutput, entryPoint, esmOutput, plugins } from '../rollup.config.part const rq = createRequire(import.meta.url); const pkg = rq('./package.json'); -const apiClients = Object.entries<{ import: string; require: string }>(pkg.exports).filter(([key]) => - key.startsWith('./rtkq/') -); - -const apiClientConfigs = apiClients.map(([name, { import: importPath }]) => { - const baseCjsOutput = cjsOutput(pkg); - const entryFileNames = name.replace('./', '') + '.cjs'; - const cjsOutputConfig = { ...baseCjsOutput, entryFileNames }; - return { - input: importPath.replace('./', ''), - - plugins, - output: [cjsOutputConfig, esmOutput(pkg, 'grafana-api-clients')], - treeshake: false, - }; -}); - export default [ { input: entryPoint, plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-api-clients')], + output: [cjsOutput(pkg, 'grafana-api-clients'), esmOutput(pkg, 'grafana-api-clients')], treeshake: false, }, { input: 'src/clients/rtkq/index.ts', plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-api-clients')], + output: [cjsOutput(pkg, 'grafana-api-clients'), esmOutput(pkg, 'grafana-api-clients')], treeshake: false, }, - ...apiClientConfigs, ]; diff --git a/packages/grafana-api-clients/src/clients/rtkq/dashboard/v0alpha1/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/dashboard/v0alpha1/endpoints.gen.ts index 5d3e72b13aa..9605b8e9355 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/dashboard/v0alpha1/endpoints.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/dashboard/v0alpha1/endpoints.gen.ts @@ -243,8 +243,11 @@ const injectedRtkApi = api type: queryArg['type'], folder: queryArg.folder, facet: queryArg.facet, + facetLimit: queryArg.facetLimit, tags: queryArg.tags, libraryPanel: queryArg.libraryPanel, + panelType: queryArg.panelType, + dataSourceType: queryArg.dataSourceType, permission: queryArg.permission, sort: queryArg.sort, limit: queryArg.limit, @@ -284,6 +287,10 @@ const injectedRtkApi = api query: (queryArg) => ({ url: `/snapshots/delete/${queryArg.deleteKey}`, method: 'DELETE' }), invalidatesTags: ['Snapshot'], }), + getSnapshotSettings: build.query({ + query: () => ({ url: `/snapshots/settings` }), + providesTags: ['Snapshot'], + }), getSnapshot: build.query({ query: (queryArg) => ({ url: `/snapshots/${queryArg.name}`, @@ -663,10 +670,16 @@ export type SearchDashboardsAndFoldersApiArg = { folder?: string; /** count distinct terms for selected fields */ facet?: string[]; + /** maximum number of terms to return per facet (default 50, max 1000) */ + facetLimit?: number; /** tag query filter */ tags?: string[]; /** find dashboards that reference a given libraryPanel */ libraryPanel?: string; + /** find dashboards using panels of a given plugin type */ + panelType?: string; + /** find dashboards using datasources of a given plugin type */ + dataSourceType?: string; /** permission needed for the resource (view, edit, admin) */ permission?: 'view' | 'edit' | 'admin'; /** sortable field */ @@ -739,6 +752,8 @@ export type DeleteWithKeyApiArg = { /** unique key returned in create */ deleteKey: string; }; +export type GetSnapshotSettingsApiResponse = /** status 200 undefined */ any; +export type GetSnapshotSettingsApiArg = void; export type GetSnapshotApiResponse = /** status 200 OK */ Snapshot; export type GetSnapshotApiArg = { /** name of the Snapshot */ @@ -1270,6 +1285,8 @@ export const { useLazyListSnapshotQuery, useCreateSnapshotMutation, useDeleteWithKeyMutation, + useGetSnapshotSettingsQuery, + useLazyGetSnapshotSettingsQuery, useGetSnapshotQuery, useLazyGetSnapshotQuery, useDeleteSnapshotMutation, diff --git a/packages/grafana-api-clients/src/clients/rtkq/iam/v0alpha1/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/iam/v0alpha1/endpoints.gen.ts index 88ce5985631..790db19a6e3 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/iam/v0alpha1/endpoints.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/iam/v0alpha1/endpoints.gen.ts @@ -3,6 +3,7 @@ export const addTagTypes = [ 'API Discovery', 'Display', 'ExternalGroupMapping', + 'Search', 'ServiceAccount', 'SSOSetting', 'TeamBinding', @@ -152,6 +153,31 @@ const injectedRtkApi = api }), invalidatesTags: ['ExternalGroupMapping'], }), + getSearchTeams: build.query({ + query: (queryArg) => ({ + url: `/searchTeams`, + params: { + query: queryArg.query, + limit: queryArg.limit, + offset: queryArg.offset, + page: queryArg.page, + }, + }), + providesTags: ['Search'], + }), + getSearchUsers: build.query({ + query: (queryArg) => ({ + url: `/searchUsers`, + params: { + query: queryArg.query, + limit: queryArg.limit, + page: queryArg.page, + offset: queryArg.offset, + sort: queryArg.sort, + }, + }), + providesTags: ['Search'], + }), listServiceAccount: build.query({ query: (queryArg) => ({ url: `/serviceaccounts`, @@ -862,6 +888,39 @@ export type UpdateExternalGroupMappingApiArg = { force?: boolean; patch: Patch; }; +export type GetSearchTeamsApiResponse = /** status 200 undefined */ { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + hits: any[]; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + maxScore: number; + offset: number; + queryCost: number; + totalHits: number; +}; +export type GetSearchTeamsApiArg = { + /** team name query string */ + query?: string; + /** limit the number of results */ + limit?: number; + /** start the query at the given offset */ + offset?: number; + /** page number to start from */ + page?: number; +}; +export type GetSearchUsersApiResponse = unknown; +export type GetSearchUsersApiArg = { + query?: string; + /** number of results to return */ + limit?: number; + /** page number (starting from 1) */ + page?: number; + /** number of results to skip */ + offset?: number; + /** sortable field */ + sort?: string; +}; export type ListServiceAccountApiResponse = /** status 200 OK */ ServiceAccountList; export type ListServiceAccountApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -2033,6 +2092,9 @@ export type UserSpec = { role: string; title: string; }; +export type UserStatus = { + lastSeenAt: number; +}; export type User = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion?: string; @@ -2041,6 +2103,7 @@ export type User = { metadata: ObjectMeta; /** Spec is the spec of the User */ spec: UserSpec; + status: UserStatus; }; export type UserList = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ @@ -2084,6 +2147,10 @@ export const { useReplaceExternalGroupMappingMutation, useDeleteExternalGroupMappingMutation, useUpdateExternalGroupMappingMutation, + useGetSearchTeamsQuery, + useLazyGetSearchTeamsQuery, + useGetSearchUsersQuery, + useLazyGetSearchUsersQuery, useListServiceAccountQuery, useLazyListServiceAccountQuery, useCreateServiceAccountMutation, diff --git a/packages/grafana-api-clients/src/clients/rtkq/index.ts b/packages/grafana-api-clients/src/clients/rtkq/index.ts index 17a471862f8..708a7b04d5b 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/index.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/index.ts @@ -9,11 +9,14 @@ import { generatedAPI as folderAPIv1beta1 } from './folder/v1beta1'; import { generatedAPI as historianAlertingAPIv0alpha1 } from './historian.alerting/v0alpha1'; import { generatedAPI as iamAPIv0alpha1 } from './iam/v0alpha1'; import { generatedAPI as logsdrilldownAPIv1alpha1 } from './logsdrilldown/v1alpha1'; +import { generatedAPI as logsdrilldownAPIv1beta1 } from './logsdrilldown/v1beta1'; import { generatedAPI as migrateToCloudAPI } from './migrate-to-cloud'; +import { generatedAPI as notificationsAlertingAPIv0alpha1 } from './notifications.alerting/v0alpha1'; import { generatedAPI as playlistAPIv0alpha1 } from './playlist/v0alpha1'; import { generatedAPI as preferencesUserAPI } from './preferences/user'; import { generatedAPI as preferencesAPIv1alpha1 } from './preferences/v1alpha1'; import { generatedAPI as provisioningAPIv0alpha1 } from './provisioning/v0alpha1'; +import { generatedAPI as rulesAlertingAPIv0alpha1 } from './rules.alerting/v0alpha1'; import { generatedAPI as shortURLAPIv1beta1 } from './shorturl/v1beta1'; import { generatedAPI as legacyUserAPI } from './user'; // PLOP_INJECT_IMPORT @@ -33,7 +36,10 @@ export const allMiddleware = [ shortURLAPIv1beta1.middleware, correlationsAPIv0alpha1.middleware, legacyUserAPI.middleware, + notificationsAlertingAPIv0alpha1.middleware, + rulesAlertingAPIv0alpha1.middleware, historianAlertingAPIv0alpha1.middleware, + logsdrilldownAPIv1beta1.middleware, logsdrilldownAPIv1alpha1.middleware, // PLOP_INJECT_MIDDLEWARE ] as const; @@ -53,8 +59,11 @@ export const allReducers = { [shortURLAPIv1beta1.reducerPath]: shortURLAPIv1beta1.reducer, [correlationsAPIv0alpha1.reducerPath]: correlationsAPIv0alpha1.reducer, [legacyUserAPI.reducerPath]: legacyUserAPI.reducer, + [notificationsAlertingAPIv0alpha1.reducerPath]: notificationsAlertingAPIv0alpha1.reducer, + [rulesAlertingAPIv0alpha1.reducerPath]: rulesAlertingAPIv0alpha1.reducer, [historianAlertingAPIv0alpha1.reducerPath]: historianAlertingAPIv0alpha1.reducer, [logsdrilldownAPIv1alpha1.reducerPath]: logsdrilldownAPIv1alpha1.reducer, + [logsdrilldownAPIv1beta1.reducerPath]: logsdrilldownAPIv1beta1.reducer, // PLOP_INJECT_REDUCER }; diff --git a/packages/grafana-api-clients/src/clients/rtkq/legacy/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/legacy/endpoints.gen.ts index 5ba0b811289..4ceed793cad 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/legacy/endpoints.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/legacy/endpoints.gen.ts @@ -658,10 +658,6 @@ const injectedRtkApi = api query: (queryArg) => ({ url: `/dashboards/db`, method: 'POST', body: queryArg.saveDashboardCommand }), invalidatesTags: ['dashboards'], }), - getHomeDashboard: build.query({ - query: () => ({ url: `/dashboards/home` }), - providesTags: ['dashboards'], - }), importDashboard: build.mutation({ query: (queryArg) => ({ url: `/dashboards/import`, method: 'POST', body: queryArg.importDashboardRequest }), invalidatesTags: ['dashboards'], @@ -1025,6 +1021,7 @@ const injectedRtkApi = api typeFilter: queryArg.typeFilter, excludeUid: queryArg.excludeUid, folderFilter: queryArg.folderFilter, + folderFilterUIDs: queryArg.folderFilterUiDs, perPage: queryArg.perPage, page: queryArg.page, }, @@ -2574,8 +2571,6 @@ export type PostDashboardApiResponse = /** status 200 (empty) */ { export type PostDashboardApiArg = { saveDashboardCommand: SaveDashboardCommand; }; -export type GetHomeDashboardApiResponse = /** status 200 (empty) */ GetHomeDashboardResponse; -export type GetHomeDashboardApiArg = void; export type ImportDashboardApiResponse = /** status 200 (empty) */ ImportDashboardResponseResponseObjectReturnedWhenImportingADashboard; export type ImportDashboardApiArg = { @@ -2921,8 +2916,11 @@ export type GetLibraryElementsApiArg = { typeFilter?: string; /** Element UID to exclude from search results. */ excludeUid?: string; - /** A comma separated list of folder ID(s) to filter the elements by. */ + /** A comma separated list of folder ID(s) to filter the elements by. + Deprecated: Use FolderFilterUIDs instead. */ folderFilter?: string; + /** A comma separated list of folder UID(s) to filter the elements by. */ + folderFilterUiDs?: string; /** The number of results per page. */ perPage?: number; /** The page for a set of records, given that only perPage records are returned at a time. Numbering starts at 1. */ @@ -3446,16 +3444,16 @@ export type RemoveTeamGroupApiQueryApiResponse = /** status 200 An OKResponse is returned if the request was successful. */ SuccessResponseBody; export type RemoveTeamGroupApiQueryApiArg = { groupId?: string; - teamId: number; + teamId: string; }; export type GetTeamGroupsApiApiResponse = /** status 200 (empty) */ TeamGroupDto[]; export type GetTeamGroupsApiApiArg = { - teamId: number; + teamId: string; }; export type AddTeamGroupApiApiResponse = /** status 200 An OKResponse is returned if the request was successful. */ SuccessResponseBody; export type AddTeamGroupApiApiArg = { - teamId: number; + teamId: string; teamGroupMapping: TeamGroupMapping; }; export type SearchTeamGroupsApiResponse = /** status 200 (empty) */ SearchTeamGroupsQueryResult; @@ -4399,51 +4397,6 @@ export type SaveDashboardCommand = { overwrite?: boolean; userId?: number; }; -export type AnnotationActions = { - canAdd?: boolean; - canDelete?: boolean; - canEdit?: boolean; -}; -export type AnnotationPermission = { - dashboard?: AnnotationActions; - organization?: AnnotationActions; -}; -export type DashboardMeta = { - annotationsPermissions?: AnnotationPermission; - apiVersion?: string; - canAdmin?: boolean; - canDelete?: boolean; - canEdit?: boolean; - canSave?: boolean; - canStar?: boolean; - created?: string; - createdBy?: string; - expires?: string; - /** Deprecated: use FolderUID instead */ - folderId?: number; - folderTitle?: string; - folderUid?: string; - folderUrl?: string; - hasAcl?: boolean; - isFolder?: boolean; - isSnapshot?: boolean; - isStarred?: boolean; - provisioned?: boolean; - provisionedExternalId?: string; - publicDashboardEnabled?: boolean; - slug?: string; - type?: string; - updated?: string; - updatedBy?: string; - url?: string; - version?: number; -}; -export type GetHomeDashboardResponse = { - dashboard?: Json; - meta?: DashboardMeta; -} & { - redirectUri?: string; -}; export type ImportDashboardResponseResponseObjectReturnedWhenImportingADashboard = { dashboardId?: number; description?: string; @@ -4535,6 +4488,45 @@ export type PublicDashboardDto = { timeSelectionEnabled?: boolean; uid?: string; }; +export type AnnotationActions = { + canAdd?: boolean; + canDelete?: boolean; + canEdit?: boolean; +}; +export type AnnotationPermission = { + dashboard?: AnnotationActions; + organization?: AnnotationActions; +}; +export type DashboardMeta = { + annotationsPermissions?: AnnotationPermission; + apiVersion?: string; + canAdmin?: boolean; + canDelete?: boolean; + canEdit?: boolean; + canSave?: boolean; + canStar?: boolean; + created?: string; + createdBy?: string; + expires?: string; + /** Deprecated: use FolderUID instead */ + folderId?: number; + folderTitle?: string; + folderUid?: string; + folderUrl?: string; + hasAcl?: boolean; + isFolder?: boolean; + isSnapshot?: boolean; + isStarred?: boolean; + provisioned?: boolean; + provisionedExternalId?: string; + publicDashboardEnabled?: boolean; + slug?: string; + type?: string; + updated?: string; + updatedBy?: string; + url?: string; + version?: number; +}; export type DashboardFullWithMeta = { dashboard?: Json; meta?: DashboardMeta; @@ -5324,7 +5316,8 @@ export type PatchPrefsCmd = { queryHistory?: QueryHistoryPreference; regionalFormat?: string; theme?: 'light' | 'dark'; - timezone?: 'utc' | 'browser'; + /** Any IANA timezone string (e.g. America/New_York), 'utc', 'browser', or empty string */ + timezone?: string; weekStart?: string; }; export type UpdatePrefsCmd = { @@ -5337,7 +5330,8 @@ export type UpdatePrefsCmd = { queryHistory?: QueryHistoryPreference; regionalFormat?: string; theme?: 'light' | 'dark' | 'system'; - timezone?: 'utc' | 'browser'; + /** Any IANA timezone string (e.g. America/New_York), 'utc', 'browser', or empty string */ + timezone?: string; weekStart?: string; }; export type OrgUserDto = { @@ -5346,6 +5340,7 @@ export type OrgUserDto = { }; authLabels?: string[]; avatarUrl?: string; + created?: string; email?: string; isDisabled?: boolean; isExternallySynced?: boolean; @@ -5566,6 +5561,7 @@ export type ReportDashboard = { }; export type Type = string; export type ReportOptions = { + csvEncoding?: string; layout?: string; orientation?: string; pdfCombineOneFile?: boolean; @@ -6123,6 +6119,7 @@ export type ChangeUserPasswordCommand = { export type UserSearchHitDto = { authLabels?: string[]; avatarUrl?: string; + created?: string; email?: string; id?: number; isAdmin?: boolean; @@ -6619,8 +6616,6 @@ export const { useSearchDashboardSnapshotsQuery, useLazySearchDashboardSnapshotsQuery, usePostDashboardMutation, - useGetHomeDashboardQuery, - useLazyGetHomeDashboardQuery, useImportDashboardMutation, useInterpolateDashboardMutation, useListPublicDashboardsQuery, diff --git a/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1alpha1/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1alpha1/endpoints.gen.ts index 835194b59e5..22464a2b3fa 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1alpha1/endpoints.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1alpha1/endpoints.gen.ts @@ -1,5 +1,10 @@ import { api } from './baseAPI'; -export const addTagTypes = ['API Discovery', 'LogsDrilldownDefaults', 'LogsDrilldown'] as const; +export const addTagTypes = [ + 'API Discovery', + 'LogsDrilldownDefaultColumns', + 'LogsDrilldownDefaults', + 'LogsDrilldown', +] as const; const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -10,6 +15,183 @@ const injectedRtkApi = api query: () => ({ url: `/` }), providesTags: ['API Discovery'], }), + listLogsDrilldownDefaultColumns: build.query< + ListLogsDrilldownDefaultColumnsApiResponse, + ListLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns`, + params: { + pretty: queryArg.pretty, + allowWatchBookmarks: queryArg.allowWatchBookmarks, + continue: queryArg['continue'], + fieldSelector: queryArg.fieldSelector, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + watch: queryArg.watch, + }, + }), + providesTags: ['LogsDrilldownDefaultColumns'], + }), + createLogsDrilldownDefaultColumns: build.mutation< + CreateLogsDrilldownDefaultColumnsApiResponse, + CreateLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns`, + method: 'POST', + body: queryArg.logsDrilldownDefaultColumns, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + deletecollectionLogsDrilldownDefaultColumns: build.mutation< + DeletecollectionLogsDrilldownDefaultColumnsApiResponse, + DeletecollectionLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + continue: queryArg['continue'], + dryRun: queryArg.dryRun, + fieldSelector: queryArg.fieldSelector, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + getLogsDrilldownDefaultColumns: build.query< + GetLogsDrilldownDefaultColumnsApiResponse, + GetLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['LogsDrilldownDefaultColumns'], + }), + replaceLogsDrilldownDefaultColumns: build.mutation< + ReplaceLogsDrilldownDefaultColumnsApiResponse, + ReplaceLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + method: 'PUT', + body: queryArg.logsDrilldownDefaultColumns, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + deleteLogsDrilldownDefaultColumns: build.mutation< + DeleteLogsDrilldownDefaultColumnsApiResponse, + DeleteLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + updateLogsDrilldownDefaultColumns: build.mutation< + UpdateLogsDrilldownDefaultColumnsApiResponse, + UpdateLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + getLogsDrilldownDefaultColumnsStatus: build.query< + GetLogsDrilldownDefaultColumnsStatusApiResponse, + GetLogsDrilldownDefaultColumnsStatusApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}/status`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['LogsDrilldownDefaultColumns'], + }), + replaceLogsDrilldownDefaultColumnsStatus: build.mutation< + ReplaceLogsDrilldownDefaultColumnsStatusApiResponse, + ReplaceLogsDrilldownDefaultColumnsStatusApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}/status`, + method: 'PUT', + body: queryArg.logsDrilldownDefaultColumns, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + updateLogsDrilldownDefaultColumnsStatus: build.mutation< + UpdateLogsDrilldownDefaultColumnsStatusApiResponse, + UpdateLogsDrilldownDefaultColumnsStatusApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}/status`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), listLogsDrilldownDefaults: build.query({ query: (queryArg) => ({ url: `/logsdrilldowndefaults`, @@ -340,6 +522,218 @@ const injectedRtkApi = api export { injectedRtkApi as generatedAPI }; export type GetApiResourcesApiResponse = /** status 200 OK */ ApiResourceList; export type GetApiResourcesApiArg = void; +export type ListLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ LogsDrilldownDefaultColumnsList; +export type ListLogsDrilldownDefaultColumnsApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean; +}; +export type CreateLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns + | /** status 202 Accepted */ LogsDrilldownDefaultColumns; +export type CreateLogsDrilldownDefaultColumnsApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + logsDrilldownDefaultColumns: LogsDrilldownDefaultColumns; +}; +export type DeletecollectionLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ Status; +export type DeletecollectionLogsDrilldownDefaultColumnsApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; +}; +export type GetLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ LogsDrilldownDefaultColumns; +export type GetLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type ReplaceLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + logsDrilldownDefaultColumns: LogsDrilldownDefaultColumns; +}; +export type DeleteLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | Status + | /** status 202 Accepted */ Status; +export type DeleteLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; +}; +export type UpdateLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type UpdateLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; +export type GetLogsDrilldownDefaultColumnsStatusApiResponse = /** status 200 OK */ LogsDrilldownDefaultColumns; +export type GetLogsDrilldownDefaultColumnsStatusApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceLogsDrilldownDefaultColumnsStatusApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type ReplaceLogsDrilldownDefaultColumnsStatusApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + logsDrilldownDefaultColumns: LogsDrilldownDefaultColumns; +}; +export type UpdateLogsDrilldownDefaultColumnsStatusApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type UpdateLogsDrilldownDefaultColumnsStatusApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; export type ListLogsDrilldownDefaultsApiResponse = /** status 200 OK */ LogsDrilldownDefaultsList; export type ListLogsDrilldownDefaultsApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -874,13 +1268,21 @@ export type ObjectMeta = { Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ uid?: string; }; -export type LogsDrilldownDefaultsSpec = { - defaultFields: string[]; - interceptDismissed: boolean; - prettifyJSON: boolean; - wrapLogMessage: boolean; +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel = { + key: string; + value: string; }; -export type LogsDrilldownDefaultsOperatorState = { +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels = LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel[]; +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord = { + columns: string[]; + labels: LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels; +}; +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords = + LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord[]; +export type LogsDrilldownDefaultColumnsSpec = { + records: LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords; +}; +export type LogsDrilldownDefaultColumnsOperatorState = { /** descriptiveState is an optional more descriptive state field which has no requirements on format */ descriptiveState?: string; /** details contains any extra information that is operator-specific */ @@ -895,7 +1297,7 @@ export type LogsDrilldownDefaultsOperatorState = { It is limited to three possible states for machine evaluation. */ state: 'success' | 'in_progress' | 'failed'; }; -export type LogsDrilldownDefaultsStatus = { +export type LogsDrilldownDefaultColumnsStatus = { /** additionalFields is reserved for future use */ additionalFields?: { [key: string]: { @@ -905,17 +1307,17 @@ export type LogsDrilldownDefaultsStatus = { /** operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ operatorStates?: { - [key: string]: LogsDrilldownDefaultsOperatorState; + [key: string]: LogsDrilldownDefaultColumnsOperatorState; }; }; -export type LogsDrilldownDefaults = { +export type LogsDrilldownDefaultColumns = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion: string; /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ kind: string; metadata: ObjectMeta; - spec: LogsDrilldownDefaultsSpec; - status?: LogsDrilldownDefaultsStatus; + spec: LogsDrilldownDefaultColumnsSpec; + status?: LogsDrilldownDefaultColumnsStatus; }; export type ListMeta = { /** continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message. */ @@ -927,10 +1329,10 @@ export type ListMeta = { /** Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. */ selfLink?: string; }; -export type LogsDrilldownDefaultsList = { +export type LogsDrilldownDefaultColumnsList = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion?: string; - items: LogsDrilldownDefaults[]; + items: LogsDrilldownDefaultColumns[]; /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ kind?: string; metadata: ListMeta; @@ -980,6 +1382,57 @@ export type Status = { status?: string; }; export type Patch = object; +export type LogsDrilldownDefaultsSpec = { + defaultFields: string[]; + interceptDismissed: boolean; + prettifyJSON: boolean; + wrapLogMessage: boolean; +}; +export type LogsDrilldownDefaultsOperatorState = { + /** descriptiveState is an optional more descriptive state field which has no requirements on format */ + descriptiveState?: string; + /** details contains any extra information that is operator-specific */ + details?: { + [key: string]: { + [key: string]: any; + }; + }; + /** lastEvaluation is the ResourceVersion last evaluated */ + lastEvaluation: string; + /** state describes the state of the lastEvaluation. + It is limited to three possible states for machine evaluation. */ + state: 'success' | 'in_progress' | 'failed'; +}; +export type LogsDrilldownDefaultsStatus = { + /** additionalFields is reserved for future use */ + additionalFields?: { + [key: string]: { + [key: string]: any; + }; + }; + /** operatorStates is a map of operator ID to operator state evaluations. + Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ + operatorStates?: { + [key: string]: LogsDrilldownDefaultsOperatorState; + }; +}; +export type LogsDrilldownDefaults = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion: string; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind: string; + metadata: ObjectMeta; + spec: LogsDrilldownDefaultsSpec; + status?: LogsDrilldownDefaultsStatus; +}; +export type LogsDrilldownDefaultsList = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + items: LogsDrilldownDefaults[]; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + metadata: ListMeta; +}; export type LogsDrilldownSpec = { defaultFields: string[]; interceptDismissed: boolean; @@ -1034,6 +1487,19 @@ export type LogsDrilldownList = { export const { useGetApiResourcesQuery, useLazyGetApiResourcesQuery, + useListLogsDrilldownDefaultColumnsQuery, + useLazyListLogsDrilldownDefaultColumnsQuery, + useCreateLogsDrilldownDefaultColumnsMutation, + useDeletecollectionLogsDrilldownDefaultColumnsMutation, + useGetLogsDrilldownDefaultColumnsQuery, + useLazyGetLogsDrilldownDefaultColumnsQuery, + useReplaceLogsDrilldownDefaultColumnsMutation, + useDeleteLogsDrilldownDefaultColumnsMutation, + useUpdateLogsDrilldownDefaultColumnsMutation, + useGetLogsDrilldownDefaultColumnsStatusQuery, + useLazyGetLogsDrilldownDefaultColumnsStatusQuery, + useReplaceLogsDrilldownDefaultColumnsStatusMutation, + useUpdateLogsDrilldownDefaultColumnsStatusMutation, useListLogsDrilldownDefaultsQuery, useLazyListLogsDrilldownDefaultsQuery, useCreateLogsDrilldownDefaultsMutation, diff --git a/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/baseAPI.ts b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/baseAPI.ts new file mode 100644 index 00000000000..484d5084e89 --- /dev/null +++ b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/baseAPI.ts @@ -0,0 +1,16 @@ +import { createApi } from '@reduxjs/toolkit/query/react'; + +import { getAPIBaseURL } from '../../../../utils/utils'; +import { createBaseQuery } from '../../createBaseQuery'; + +export const API_GROUP = 'logsdrilldown.grafana.app' as const; +export const API_VERSION = 'v1beta1' as const; +export const BASE_URL = getAPIBaseURL(API_GROUP, API_VERSION); + +export const api = createApi({ + reducerPath: 'logsdrilldownAPIv1beta1', + baseQuery: createBaseQuery({ + baseURL: BASE_URL, + }), + endpoints: () => ({}), +}); diff --git a/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/endpoints.gen.ts new file mode 100644 index 00000000000..65395d2279d --- /dev/null +++ b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/endpoints.gen.ts @@ -0,0 +1,652 @@ +import { api } from './baseAPI'; +export const addTagTypes = ['API Discovery', 'LogsDrilldownDefaultColumns'] as const; +const injectedRtkApi = api + .enhanceEndpoints({ + addTagTypes, + }) + .injectEndpoints({ + endpoints: (build) => ({ + getApiResources: build.query({ + query: () => ({ url: `/` }), + providesTags: ['API Discovery'], + }), + listLogsDrilldownDefaultColumns: build.query< + ListLogsDrilldownDefaultColumnsApiResponse, + ListLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns`, + params: { + pretty: queryArg.pretty, + allowWatchBookmarks: queryArg.allowWatchBookmarks, + continue: queryArg['continue'], + fieldSelector: queryArg.fieldSelector, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + watch: queryArg.watch, + }, + }), + providesTags: ['LogsDrilldownDefaultColumns'], + }), + createLogsDrilldownDefaultColumns: build.mutation< + CreateLogsDrilldownDefaultColumnsApiResponse, + CreateLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns`, + method: 'POST', + body: queryArg.logsDrilldownDefaultColumns, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + deletecollectionLogsDrilldownDefaultColumns: build.mutation< + DeletecollectionLogsDrilldownDefaultColumnsApiResponse, + DeletecollectionLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + continue: queryArg['continue'], + dryRun: queryArg.dryRun, + fieldSelector: queryArg.fieldSelector, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + getLogsDrilldownDefaultColumns: build.query< + GetLogsDrilldownDefaultColumnsApiResponse, + GetLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['LogsDrilldownDefaultColumns'], + }), + replaceLogsDrilldownDefaultColumns: build.mutation< + ReplaceLogsDrilldownDefaultColumnsApiResponse, + ReplaceLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + method: 'PUT', + body: queryArg.logsDrilldownDefaultColumns, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + deleteLogsDrilldownDefaultColumns: build.mutation< + DeleteLogsDrilldownDefaultColumnsApiResponse, + DeleteLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + updateLogsDrilldownDefaultColumns: build.mutation< + UpdateLogsDrilldownDefaultColumnsApiResponse, + UpdateLogsDrilldownDefaultColumnsApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + getLogsDrilldownDefaultColumnsStatus: build.query< + GetLogsDrilldownDefaultColumnsStatusApiResponse, + GetLogsDrilldownDefaultColumnsStatusApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}/status`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['LogsDrilldownDefaultColumns'], + }), + replaceLogsDrilldownDefaultColumnsStatus: build.mutation< + ReplaceLogsDrilldownDefaultColumnsStatusApiResponse, + ReplaceLogsDrilldownDefaultColumnsStatusApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}/status`, + method: 'PUT', + body: queryArg.logsDrilldownDefaultColumns, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + updateLogsDrilldownDefaultColumnsStatus: build.mutation< + UpdateLogsDrilldownDefaultColumnsStatusApiResponse, + UpdateLogsDrilldownDefaultColumnsStatusApiArg + >({ + query: (queryArg) => ({ + url: `/logsdrilldowndefaultcolumns/${queryArg.name}/status`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['LogsDrilldownDefaultColumns'], + }), + }), + overrideExisting: false, + }); +export { injectedRtkApi as generatedAPI }; +export type GetApiResourcesApiResponse = /** status 200 OK */ ApiResourceList; +export type GetApiResourcesApiArg = void; +export type ListLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ LogsDrilldownDefaultColumnsList; +export type ListLogsDrilldownDefaultColumnsApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean; +}; +export type CreateLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns + | /** status 202 Accepted */ LogsDrilldownDefaultColumns; +export type CreateLogsDrilldownDefaultColumnsApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + logsDrilldownDefaultColumns: LogsDrilldownDefaultColumns; +}; +export type DeletecollectionLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ Status; +export type DeletecollectionLogsDrilldownDefaultColumnsApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; +}; +export type GetLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ LogsDrilldownDefaultColumns; +export type GetLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type ReplaceLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + logsDrilldownDefaultColumns: LogsDrilldownDefaultColumns; +}; +export type DeleteLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | Status + | /** status 202 Accepted */ Status; +export type DeleteLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; +}; +export type UpdateLogsDrilldownDefaultColumnsApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type UpdateLogsDrilldownDefaultColumnsApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; +export type GetLogsDrilldownDefaultColumnsStatusApiResponse = /** status 200 OK */ LogsDrilldownDefaultColumns; +export type GetLogsDrilldownDefaultColumnsStatusApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceLogsDrilldownDefaultColumnsStatusApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type ReplaceLogsDrilldownDefaultColumnsStatusApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + logsDrilldownDefaultColumns: LogsDrilldownDefaultColumns; +}; +export type UpdateLogsDrilldownDefaultColumnsStatusApiResponse = /** status 200 OK */ + | LogsDrilldownDefaultColumns + | /** status 201 Created */ LogsDrilldownDefaultColumns; +export type UpdateLogsDrilldownDefaultColumnsStatusApiArg = { + /** name of the LogsDrilldownDefaultColumns */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; +export type ApiResource = { + /** categories is a list of the grouped resources this resource belongs to (e.g. 'all') */ + categories?: string[]; + /** group is the preferred group of the resource. Empty implies the group of the containing resource list. For subresources, this may have a different value, for example: Scale". */ + group?: string; + /** kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo') */ + kind: string; + /** name is the plural name of the resource. */ + name: string; + /** namespaced indicates if a resource is namespaced or not. */ + namespaced: boolean; + /** shortNames is a list of suggested short names of the resource. */ + shortNames?: string[]; + /** singularName is the singular name of the resource. This allows clients to handle plural and singular opaquely. The singularName is more correct for reporting status on a single item and both singular and plural are allowed from the kubectl CLI interface. */ + singularName: string; + /** The hash value of the storage version, the version this resource is converted to when written to the data store. Value must be treated as opaque by clients. Only equality comparison on the value is valid. This is an alpha feature and may change or be removed in the future. The field is populated by the apiserver only if the StorageVersionHash feature gate is enabled. This field will remain optional even if it graduates. */ + storageVersionHash?: string; + /** verbs is a list of supported kube verbs (this includes get, list, watch, create, update, patch, delete, deletecollection, and proxy) */ + verbs: string[]; + /** version is the preferred version of the resource. Empty implies the version of the containing resource list For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)". */ + version?: string; +}; +export type ApiResourceList = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + /** groupVersion is the group and version this APIResourceList is for. */ + groupVersion: string; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** resources contains the name of the resources and if they are namespaced. */ + resources: ApiResource[]; +}; +export type Time = string; +export type FieldsV1 = object; +export type ManagedFieldsEntry = { + /** APIVersion defines the version of this resource that this field set applies to. The format is "group/version" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted. */ + apiVersion?: string; + /** FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: "FieldsV1" */ + fieldsType?: string; + /** FieldsV1 holds the first JSON version format as described in the "FieldsV1" type. */ + fieldsV1?: FieldsV1; + /** Manager is an identifier of the workflow managing these fields. */ + manager?: string; + /** Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'. */ + operation?: string; + /** Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource. */ + subresource?: string; + /** Time is the timestamp of when the ManagedFields entry was added. The timestamp will also be updated if a field is added, the manager changes any of the owned fields value or removes a field. The timestamp does not update when a field is removed from the entry because another manager took it over. */ + time?: Time; +}; +export type OwnerReference = { + /** API version of the referent. */ + apiVersion: string; + /** If true, AND if the owner has the "foregroundDeletion" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion for how the garbage collector interacts with this field and enforces the foreground deletion. Defaults to false. To set this field, a user needs "delete" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned. */ + blockOwnerDeletion?: boolean; + /** If true, this reference points to the managing controller. */ + controller?: boolean; + /** Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind: string; + /** Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names */ + name: string; + /** UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ + uid: string; +}; +export type ObjectMeta = { + /** Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations */ + annotations?: { + [key: string]: string; + }; + /** CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC. + + Populated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata */ + creationTimestamp?: Time; + /** Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only. */ + deletionGracePeriodSeconds?: number; + /** DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested. + + Populated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata */ + deletionTimestamp?: Time; + /** Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list. */ + finalizers?: string[]; + /** GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server. + + If this field is specified and the generated name exists, the server will return a 409. + + Applied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency */ + generateName?: string; + /** A sequence number representing a specific generation of the desired state. Populated by the system. Read-only. */ + generation?: number; + /** Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels */ + labels?: { + [key: string]: string; + }; + /** ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like "ci-cd". The set of fields is always in the version that the workflow used when modifying the object. */ + managedFields?: ManagedFieldsEntry[]; + /** Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names */ + name?: string; + /** Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the "default" namespace, but "default" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty. + + Must be a DNS_LABEL. Cannot be updated. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces */ + namespace?: string; + /** List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller. */ + ownerReferences?: OwnerReference[]; + /** An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources. + + Populated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency */ + resourceVersion?: string; + /** Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. */ + selfLink?: string; + /** UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations. + + Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ + uid?: string; +}; +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel = { + key: string; + value: string; +}; +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels = LogsDrilldownDefaultColumnsLogsDefaultColumnsLabel[]; +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord = { + columns: string[]; + labels: LogsDrilldownDefaultColumnsLogsDefaultColumnsLabels; +}; +export type LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords = + LogsDrilldownDefaultColumnsLogsDefaultColumnsRecord[]; +export type LogsDrilldownDefaultColumnsSpec = { + records: LogsDrilldownDefaultColumnsLogsDefaultColumnsRecords; +}; +export type LogsDrilldownDefaultColumnsOperatorState = { + /** descriptiveState is an optional more descriptive state field which has no requirements on format */ + descriptiveState?: string; + /** details contains any extra information that is operator-specific */ + details?: { + [key: string]: { + [key: string]: any; + }; + }; + /** lastEvaluation is the ResourceVersion last evaluated */ + lastEvaluation: string; + /** state describes the state of the lastEvaluation. + It is limited to three possible states for machine evaluation. */ + state: 'success' | 'in_progress' | 'failed'; +}; +export type LogsDrilldownDefaultColumnsStatus = { + /** additionalFields is reserved for future use */ + additionalFields?: { + [key: string]: { + [key: string]: any; + }; + }; + /** operatorStates is a map of operator ID to operator state evaluations. + Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ + operatorStates?: { + [key: string]: LogsDrilldownDefaultColumnsOperatorState; + }; +}; +export type LogsDrilldownDefaultColumns = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion: string; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind: string; + metadata: ObjectMeta; + spec: LogsDrilldownDefaultColumnsSpec; + status?: LogsDrilldownDefaultColumnsStatus; +}; +export type ListMeta = { + /** continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message. */ + continue?: string; + /** remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact. */ + remainingItemCount?: number; + /** String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency */ + resourceVersion?: string; + /** Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. */ + selfLink?: string; +}; +export type LogsDrilldownDefaultColumnsList = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + items: LogsDrilldownDefaultColumns[]; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + metadata: ListMeta; +}; +export type StatusCause = { + /** The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional. + + Examples: + "name" - the field "name" on the current resource + "items[0].name" - the field "name" on the first array entry in "items" */ + field?: string; + /** A human-readable description of the cause of the error. This field may be presented as-is to a reader. */ + message?: string; + /** A machine-readable description of the cause of the error. If this value is empty there is no information available. */ + reason?: string; +}; +export type StatusDetails = { + /** The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes. */ + causes?: StatusCause[]; + /** The group attribute of the resource associated with the status StatusReason. */ + group?: string; + /** The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described). */ + name?: string; + /** If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. */ + retryAfterSeconds?: number; + /** UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ + uid?: string; +}; +export type Status = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + /** Suggested HTTP return code for this status, 0 if not set. */ + code?: number; + /** Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type. */ + details?: StatusDetails; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** A human-readable description of the status of this operation. */ + message?: string; + /** Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + metadata?: ListMeta; + /** A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it. */ + reason?: string; + /** Status of the operation. One of: "Success" or "Failure". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status */ + status?: string; +}; +export type Patch = object; +export const { + useGetApiResourcesQuery, + useLazyGetApiResourcesQuery, + useListLogsDrilldownDefaultColumnsQuery, + useLazyListLogsDrilldownDefaultColumnsQuery, + useCreateLogsDrilldownDefaultColumnsMutation, + useDeletecollectionLogsDrilldownDefaultColumnsMutation, + useGetLogsDrilldownDefaultColumnsQuery, + useLazyGetLogsDrilldownDefaultColumnsQuery, + useReplaceLogsDrilldownDefaultColumnsMutation, + useDeleteLogsDrilldownDefaultColumnsMutation, + useUpdateLogsDrilldownDefaultColumnsMutation, + useGetLogsDrilldownDefaultColumnsStatusQuery, + useLazyGetLogsDrilldownDefaultColumnsStatusQuery, + useReplaceLogsDrilldownDefaultColumnsStatusMutation, + useUpdateLogsDrilldownDefaultColumnsStatusMutation, +} = injectedRtkApi; diff --git a/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/index.ts b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/index.ts new file mode 100644 index 00000000000..d80fd6d553a --- /dev/null +++ b/packages/grafana-api-clients/src/clients/rtkq/logsdrilldown/v1beta1/index.ts @@ -0,0 +1,5 @@ +export { BASE_URL, API_GROUP, API_VERSION } from './baseAPI'; +import { generatedAPI as rawAPI } from './endpoints.gen'; + +export * from './endpoints.gen'; +export const generatedAPI = rawAPI.enhanceEndpoints({}); diff --git a/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/baseAPI.ts b/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/baseAPI.ts new file mode 100644 index 00000000000..f302218e275 --- /dev/null +++ b/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/baseAPI.ts @@ -0,0 +1,16 @@ +import { createApi } from '@reduxjs/toolkit/query/react'; + +import { getAPIBaseURL } from '../../../../utils/utils'; +import { createBaseQuery } from '../../createBaseQuery'; + +export const API_GROUP = 'notifications.alerting.grafana.app' as const; +export const API_VERSION = 'v0alpha1' as const; +export const BASE_URL = getAPIBaseURL(API_GROUP, API_VERSION); + +export const api = createApi({ + reducerPath: 'notificationsAlertingAPIv0alpha1', + baseQuery: createBaseQuery({ + baseURL: BASE_URL, + }), + endpoints: () => ({}), +}); diff --git a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/notifications.api.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/endpoints.gen.ts similarity index 82% rename from packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/notifications.api.gen.ts rename to packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/endpoints.gen.ts index 66b145753a6..35301a132fc 100644 --- a/packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/notifications.api.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/endpoints.gen.ts @@ -1,4 +1,4 @@ -import { api } from './api'; +import { api } from './baseAPI'; export const addTagTypes = ['API Discovery', 'Receiver', 'RoutingTree', 'TemplateGroup', 'TimeInterval'] as const; const injectedRtkApi = api .enhanceEndpoints({ @@ -7,7 +7,7 @@ const injectedRtkApi = api .injectEndpoints({ endpoints: (build) => ({ getApiResources: build.query({ - query: () => ({ url: `/apis/notifications.alerting.grafana.app/v0alpha1/` }), + query: () => ({ url: `/` }), providesTags: ['API Discovery'], }), listReceiver: build.query({ @@ -119,44 +119,6 @@ const injectedRtkApi = api }), invalidatesTags: ['Receiver'], }), - getReceiverStatus: build.query({ - query: (queryArg) => ({ - url: `/receivers/${queryArg.name}/status`, - params: { - pretty: queryArg.pretty, - }, - }), - providesTags: ['Receiver'], - }), - replaceReceiverStatus: build.mutation({ - query: (queryArg) => ({ - url: `/receivers/${queryArg.name}/status`, - method: 'PUT', - body: queryArg.receiver, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - }, - }), - invalidatesTags: ['Receiver'], - }), - updateReceiverStatus: build.mutation({ - query: (queryArg) => ({ - url: `/receivers/${queryArg.name}/status`, - method: 'PATCH', - body: queryArg.patch, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - force: queryArg.force, - }, - }), - invalidatesTags: ['Receiver'], - }), listRoutingTree: build.query({ query: (queryArg) => ({ url: `/routingtrees`, @@ -269,44 +231,6 @@ const injectedRtkApi = api }), invalidatesTags: ['RoutingTree'], }), - getRoutingTreeStatus: build.query({ - query: (queryArg) => ({ - url: `/routingtrees/${queryArg.name}/status`, - params: { - pretty: queryArg.pretty, - }, - }), - providesTags: ['RoutingTree'], - }), - replaceRoutingTreeStatus: build.mutation({ - query: (queryArg) => ({ - url: `/routingtrees/${queryArg.name}/status`, - method: 'PUT', - body: queryArg.routingTree, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - }, - }), - invalidatesTags: ['RoutingTree'], - }), - updateRoutingTreeStatus: build.mutation({ - query: (queryArg) => ({ - url: `/routingtrees/${queryArg.name}/status`, - method: 'PATCH', - body: queryArg.patch, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - force: queryArg.force, - }, - }), - invalidatesTags: ['RoutingTree'], - }), listTemplateGroup: build.query({ query: (queryArg) => ({ url: `/templategroups`, @@ -419,47 +343,6 @@ const injectedRtkApi = api }), invalidatesTags: ['TemplateGroup'], }), - getTemplateGroupStatus: build.query({ - query: (queryArg) => ({ - url: `/templategroups/${queryArg.name}/status`, - params: { - pretty: queryArg.pretty, - }, - }), - providesTags: ['TemplateGroup'], - }), - replaceTemplateGroupStatus: build.mutation< - ReplaceTemplateGroupStatusApiResponse, - ReplaceTemplateGroupStatusApiArg - >({ - query: (queryArg) => ({ - url: `/templategroups/${queryArg.name}/status`, - method: 'PUT', - body: queryArg.templateGroup, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - }, - }), - invalidatesTags: ['TemplateGroup'], - }), - updateTemplateGroupStatus: build.mutation({ - query: (queryArg) => ({ - url: `/templategroups/${queryArg.name}/status`, - method: 'PATCH', - body: queryArg.patch, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - force: queryArg.force, - }, - }), - invalidatesTags: ['TemplateGroup'], - }), listTimeInterval: build.query({ query: (queryArg) => ({ url: `/timeintervals`, @@ -572,48 +455,10 @@ const injectedRtkApi = api }), invalidatesTags: ['TimeInterval'], }), - getTimeIntervalStatus: build.query({ - query: (queryArg) => ({ - url: `/timeintervals/${queryArg.name}/status`, - params: { - pretty: queryArg.pretty, - }, - }), - providesTags: ['TimeInterval'], - }), - replaceTimeIntervalStatus: build.mutation({ - query: (queryArg) => ({ - url: `/timeintervals/${queryArg.name}/status`, - method: 'PUT', - body: queryArg.timeInterval, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - }, - }), - invalidatesTags: ['TimeInterval'], - }), - updateTimeIntervalStatus: build.mutation({ - query: (queryArg) => ({ - url: `/timeintervals/${queryArg.name}/status`, - method: 'PATCH', - body: queryArg.patch, - params: { - pretty: queryArg.pretty, - dryRun: queryArg.dryRun, - fieldManager: queryArg.fieldManager, - fieldValidation: queryArg.fieldValidation, - force: queryArg.force, - }, - }), - invalidatesTags: ['TimeInterval'], - }), }), overrideExisting: false, }); -export { injectedRtkApi as notificationsAPI }; +export { injectedRtkApi as generatedAPI }; export type GetApiResourcesApiResponse = /** status 200 OK */ ApiResourceList; export type GetApiResourcesApiArg = void; export type ListReceiverApiResponse = /** status 200 OK */ ReceiverList; @@ -781,43 +626,6 @@ export type UpdateReceiverApiArg = { force?: boolean; patch: Patch; }; -export type GetReceiverStatusApiResponse = /** status 200 OK */ Receiver; -export type GetReceiverStatusApiArg = { - /** name of the Receiver */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; -}; -export type ReplaceReceiverStatusApiResponse = /** status 200 OK */ Receiver | /** status 201 Created */ Receiver; -export type ReplaceReceiverStatusApiArg = { - /** name of the Receiver */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - receiver: Receiver; -}; -export type UpdateReceiverStatusApiResponse = /** status 200 OK */ Receiver | /** status 201 Created */ Receiver; -export type UpdateReceiverStatusApiArg = { - /** name of the Receiver */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ - force?: boolean; - patch: Patch; -}; export type ListRoutingTreeApiResponse = /** status 200 OK */ RoutingTreeList; export type ListRoutingTreeApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -983,47 +791,6 @@ export type UpdateRoutingTreeApiArg = { force?: boolean; patch: Patch; }; -export type GetRoutingTreeStatusApiResponse = /** status 200 OK */ RoutingTree; -export type GetRoutingTreeStatusApiArg = { - /** name of the RoutingTree */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; -}; -export type ReplaceRoutingTreeStatusApiResponse = /** status 200 OK */ - | RoutingTree - | /** status 201 Created */ RoutingTree; -export type ReplaceRoutingTreeStatusApiArg = { - /** name of the RoutingTree */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - routingTree: RoutingTree; -}; -export type UpdateRoutingTreeStatusApiResponse = /** status 200 OK */ - | RoutingTree - | /** status 201 Created */ RoutingTree; -export type UpdateRoutingTreeStatusApiArg = { - /** name of the RoutingTree */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ - force?: boolean; - patch: Patch; -}; export type ListTemplateGroupApiResponse = /** status 200 OK */ TemplateGroupList; export type ListTemplateGroupApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -1193,47 +960,6 @@ export type UpdateTemplateGroupApiArg = { force?: boolean; patch: Patch; }; -export type GetTemplateGroupStatusApiResponse = /** status 200 OK */ TemplateGroup; -export type GetTemplateGroupStatusApiArg = { - /** name of the TemplateGroup */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; -}; -export type ReplaceTemplateGroupStatusApiResponse = /** status 200 OK */ - | TemplateGroup - | /** status 201 Created */ TemplateGroup; -export type ReplaceTemplateGroupStatusApiArg = { - /** name of the TemplateGroup */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - templateGroup: TemplateGroup; -}; -export type UpdateTemplateGroupStatusApiResponse = /** status 200 OK */ - | TemplateGroup - | /** status 201 Created */ TemplateGroup; -export type UpdateTemplateGroupStatusApiArg = { - /** name of the TemplateGroup */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ - force?: boolean; - patch: Patch; -}; export type ListTimeIntervalApiResponse = /** status 200 OK */ TimeIntervalList; export type ListTimeIntervalApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -1399,47 +1125,6 @@ export type UpdateTimeIntervalApiArg = { force?: boolean; patch: Patch; }; -export type GetTimeIntervalStatusApiResponse = /** status 200 OK */ TimeInterval; -export type GetTimeIntervalStatusApiArg = { - /** name of the TimeInterval */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; -}; -export type ReplaceTimeIntervalStatusApiResponse = /** status 200 OK */ - | TimeInterval - | /** status 201 Created */ TimeInterval; -export type ReplaceTimeIntervalStatusApiArg = { - /** name of the TimeInterval */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - timeInterval: TimeInterval; -}; -export type UpdateTimeIntervalStatusApiResponse = /** status 200 OK */ - | TimeInterval - | /** status 201 Created */ TimeInterval; -export type UpdateTimeIntervalStatusApiArg = { - /** name of the TimeInterval */ - name: string; - /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ - pretty?: string; - /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ - dryRun?: string; - /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ - fieldManager?: string; - /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ - fieldValidation?: string; - /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ - force?: boolean; - patch: Patch; -}; export type ApiResource = { /** categories is a list of the grouped resources this resource belongs to (e.g. 'all') */ categories?: string[]; @@ -1572,34 +1257,6 @@ export type ReceiverSpec = { integrations: ReceiverIntegration[]; title: string; }; -export type ReceiverOperatorState = { - /** descriptiveState is an optional more descriptive state field which has no requirements on format */ - descriptiveState?: string; - /** details contains any extra information that is operator-specific */ - details?: { - [key: string]: { - [key: string]: any; - }; - }; - /** lastEvaluation is the ResourceVersion last evaluated */ - lastEvaluation: string; - /** state describes the state of the lastEvaluation. - It is limited to three possible states for machine evaluation. */ - state: 'success' | 'in_progress' | 'failed'; -}; -export type ReceiverStatus = { - /** additionalFields is reserved for future use */ - additionalFields?: { - [key: string]: { - [key: string]: any; - }; - }; - /** operatorStates is a map of operator ID to operator state evaluations. - Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ - operatorStates?: { - [key: string]: ReceiverOperatorState; - }; -}; export type Receiver = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion: string; @@ -1607,7 +1264,6 @@ export type Receiver = { kind: string; metadata: ObjectMeta; spec: ReceiverSpec; - status?: ReceiverStatus; }; export type ListMeta = { /** continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message. */ @@ -1700,34 +1356,6 @@ export type RoutingTreeSpec = { defaults: RoutingTreeRouteDefaults; routes: RoutingTreeRoute[]; }; -export type RoutingTreeOperatorState = { - /** descriptiveState is an optional more descriptive state field which has no requirements on format */ - descriptiveState?: string; - /** details contains any extra information that is operator-specific */ - details?: { - [key: string]: { - [key: string]: any; - }; - }; - /** lastEvaluation is the ResourceVersion last evaluated */ - lastEvaluation: string; - /** state describes the state of the lastEvaluation. - It is limited to three possible states for machine evaluation. */ - state: 'success' | 'in_progress' | 'failed'; -}; -export type RoutingTreeStatus = { - /** additionalFields is reserved for future use */ - additionalFields?: { - [key: string]: { - [key: string]: any; - }; - }; - /** operatorStates is a map of operator ID to operator state evaluations. - Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ - operatorStates?: { - [key: string]: RoutingTreeOperatorState; - }; -}; export type RoutingTree = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion: string; @@ -1735,7 +1363,6 @@ export type RoutingTree = { kind: string; metadata: ObjectMeta; spec: RoutingTreeSpec; - status?: RoutingTreeStatus; }; export type RoutingTreeList = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ @@ -1745,38 +1372,12 @@ export type RoutingTreeList = { kind?: string; metadata: ListMeta; }; +export type TemplateGroupTemplateKind = 'grafana' | 'mimir'; export type TemplateGroupSpec = { content: string; + kind: TemplateGroupTemplateKind; title: string; }; -export type TemplateGroupOperatorState = { - /** descriptiveState is an optional more descriptive state field which has no requirements on format */ - descriptiveState?: string; - /** details contains any extra information that is operator-specific */ - details?: { - [key: string]: { - [key: string]: any; - }; - }; - /** lastEvaluation is the ResourceVersion last evaluated */ - lastEvaluation: string; - /** state describes the state of the lastEvaluation. - It is limited to three possible states for machine evaluation. */ - state: 'success' | 'in_progress' | 'failed'; -}; -export type TemplateGroupStatus = { - /** additionalFields is reserved for future use */ - additionalFields?: { - [key: string]: { - [key: string]: any; - }; - }; - /** operatorStates is a map of operator ID to operator state evaluations. - Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ - operatorStates?: { - [key: string]: TemplateGroupOperatorState; - }; -}; export type TemplateGroup = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion: string; @@ -1784,7 +1385,6 @@ export type TemplateGroup = { kind: string; metadata: ObjectMeta; spec: TemplateGroupSpec; - status?: TemplateGroupStatus; }; export type TemplateGroupList = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ @@ -1810,34 +1410,6 @@ export type TimeIntervalSpec = { name: string; time_intervals: TimeIntervalInterval[]; }; -export type TimeIntervalOperatorState = { - /** descriptiveState is an optional more descriptive state field which has no requirements on format */ - descriptiveState?: string; - /** details contains any extra information that is operator-specific */ - details?: { - [key: string]: { - [key: string]: any; - }; - }; - /** lastEvaluation is the ResourceVersion last evaluated */ - lastEvaluation: string; - /** state describes the state of the lastEvaluation. - It is limited to three possible states for machine evaluation. */ - state: 'success' | 'in_progress' | 'failed'; -}; -export type TimeIntervalStatus = { - /** additionalFields is reserved for future use */ - additionalFields?: { - [key: string]: { - [key: string]: any; - }; - }; - /** operatorStates is a map of operator ID to operator state evaluations. - Any operator which consumes this kind SHOULD add its state evaluation information to this field. */ - operatorStates?: { - [key: string]: TimeIntervalOperatorState; - }; -}; export type TimeInterval = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion: string; @@ -1845,7 +1417,6 @@ export type TimeInterval = { kind: string; metadata: ObjectMeta; spec: TimeIntervalSpec; - status?: TimeIntervalStatus; }; export type TimeIntervalList = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ @@ -1855,3 +1426,43 @@ export type TimeIntervalList = { kind?: string; metadata: ListMeta; }; +export const { + useGetApiResourcesQuery, + useLazyGetApiResourcesQuery, + useListReceiverQuery, + useLazyListReceiverQuery, + useCreateReceiverMutation, + useDeletecollectionReceiverMutation, + useGetReceiverQuery, + useLazyGetReceiverQuery, + useReplaceReceiverMutation, + useDeleteReceiverMutation, + useUpdateReceiverMutation, + useListRoutingTreeQuery, + useLazyListRoutingTreeQuery, + useCreateRoutingTreeMutation, + useDeletecollectionRoutingTreeMutation, + useGetRoutingTreeQuery, + useLazyGetRoutingTreeQuery, + useReplaceRoutingTreeMutation, + useDeleteRoutingTreeMutation, + useUpdateRoutingTreeMutation, + useListTemplateGroupQuery, + useLazyListTemplateGroupQuery, + useCreateTemplateGroupMutation, + useDeletecollectionTemplateGroupMutation, + useGetTemplateGroupQuery, + useLazyGetTemplateGroupQuery, + useReplaceTemplateGroupMutation, + useDeleteTemplateGroupMutation, + useUpdateTemplateGroupMutation, + useListTimeIntervalQuery, + useLazyListTimeIntervalQuery, + useCreateTimeIntervalMutation, + useDeletecollectionTimeIntervalMutation, + useGetTimeIntervalQuery, + useLazyGetTimeIntervalQuery, + useReplaceTimeIntervalMutation, + useDeleteTimeIntervalMutation, + useUpdateTimeIntervalMutation, +} = injectedRtkApi; diff --git a/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/index.ts b/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/index.ts new file mode 100644 index 00000000000..d80fd6d553a --- /dev/null +++ b/packages/grafana-api-clients/src/clients/rtkq/notifications.alerting/v0alpha1/index.ts @@ -0,0 +1,5 @@ +export { BASE_URL, API_GROUP, API_VERSION } from './baseAPI'; +import { generatedAPI as rawAPI } from './endpoints.gen'; + +export * from './endpoints.gen'; +export const generatedAPI = rawAPI.enhanceEndpoints({}); diff --git a/packages/grafana-api-clients/src/clients/rtkq/preferences/user/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/preferences/user/endpoints.gen.ts index 71107ce1072..93b5259f144 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/preferences/user/endpoints.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/preferences/user/endpoints.gen.ts @@ -86,7 +86,8 @@ export type PatchPrefsCmd = { queryHistory?: QueryHistoryPreference; regionalFormat?: string; theme?: 'light' | 'dark'; - timezone?: 'utc' | 'browser'; + /** Any IANA timezone string (e.g. America/New_York), 'utc', 'browser', or empty string */ + timezone?: string; weekStart?: string; }; export type UpdatePrefsCmd = { @@ -99,7 +100,8 @@ export type UpdatePrefsCmd = { queryHistory?: QueryHistoryPreference; regionalFormat?: string; theme?: 'light' | 'dark' | 'system'; - timezone?: 'utc' | 'browser'; + /** Any IANA timezone string (e.g. America/New_York), 'utc', 'browser', or empty string */ + timezone?: string; weekStart?: string; }; export const { diff --git a/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts index 7ef1fc4fc91..40d4299a1a0 100644 --- a/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/provisioning/v0alpha1/endpoints.gen.ts @@ -1,5 +1,5 @@ import { api } from './baseAPI'; -export const addTagTypes = ['API Discovery', 'Job', 'Repository', 'Provisioning'] as const; +export const addTagTypes = ['API Discovery', 'Connection', 'Job', 'Repository', 'Provisioning'] as const; const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -10,6 +10,160 @@ const injectedRtkApi = api query: () => ({ url: `/` }), providesTags: ['API Discovery'], }), + listConnection: build.query({ + query: (queryArg) => ({ + url: `/connections`, + params: { + pretty: queryArg.pretty, + allowWatchBookmarks: queryArg.allowWatchBookmarks, + continue: queryArg['continue'], + fieldSelector: queryArg.fieldSelector, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + watch: queryArg.watch, + }, + }), + providesTags: ['Connection'], + }), + createConnection: build.mutation({ + query: (queryArg) => ({ + url: `/connections`, + method: 'POST', + body: queryArg.connection, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['Connection'], + }), + deletecollectionConnection: build.mutation< + DeletecollectionConnectionApiResponse, + DeletecollectionConnectionApiArg + >({ + query: (queryArg) => ({ + url: `/connections`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + continue: queryArg['continue'], + dryRun: queryArg.dryRun, + fieldSelector: queryArg.fieldSelector, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + labelSelector: queryArg.labelSelector, + limit: queryArg.limit, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + resourceVersion: queryArg.resourceVersion, + resourceVersionMatch: queryArg.resourceVersionMatch, + sendInitialEvents: queryArg.sendInitialEvents, + timeoutSeconds: queryArg.timeoutSeconds, + }, + }), + invalidatesTags: ['Connection'], + }), + getConnection: build.query({ + query: (queryArg) => ({ + url: `/connections/${queryArg.name}`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['Connection'], + }), + replaceConnection: build.mutation({ + query: (queryArg) => ({ + url: `/connections/${queryArg.name}`, + method: 'PUT', + body: queryArg.connection, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['Connection'], + }), + deleteConnection: build.mutation({ + query: (queryArg) => ({ + url: `/connections/${queryArg.name}`, + method: 'DELETE', + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + gracePeriodSeconds: queryArg.gracePeriodSeconds, + ignoreStoreReadErrorWithClusterBreakingPotential: queryArg.ignoreStoreReadErrorWithClusterBreakingPotential, + orphanDependents: queryArg.orphanDependents, + propagationPolicy: queryArg.propagationPolicy, + }, + }), + invalidatesTags: ['Connection'], + }), + updateConnection: build.mutation({ + query: (queryArg) => ({ + url: `/connections/${queryArg.name}`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['Connection'], + }), + getConnectionRepositories: build.query({ + query: (queryArg) => ({ url: `/connections/${queryArg.name}/repositories` }), + providesTags: ['Connection'], + }), + getConnectionStatus: build.query({ + query: (queryArg) => ({ + url: `/connections/${queryArg.name}/status`, + params: { + pretty: queryArg.pretty, + }, + }), + providesTags: ['Connection'], + }), + replaceConnectionStatus: build.mutation({ + query: (queryArg) => ({ + url: `/connections/${queryArg.name}/status`, + method: 'PUT', + body: queryArg.connection, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + }, + }), + invalidatesTags: ['Connection'], + }), + updateConnectionStatus: build.mutation({ + query: (queryArg) => ({ + url: `/connections/${queryArg.name}/status`, + method: 'PATCH', + body: queryArg.patch, + params: { + pretty: queryArg.pretty, + dryRun: queryArg.dryRun, + fieldManager: queryArg.fieldManager, + fieldValidation: queryArg.fieldValidation, + force: queryArg.force, + }, + }), + invalidatesTags: ['Connection'], + }), listJob: build.query({ query: (queryArg) => ({ url: `/jobs`, @@ -411,6 +565,220 @@ const injectedRtkApi = api export { injectedRtkApi as generatedAPI }; export type GetApiResourcesApiResponse = /** status 200 OK */ ApiResourceList; export type GetApiResourcesApiArg = void; +export type ListConnectionApiResponse = /** status 200 OK */ ConnectionList; +export type ListConnectionApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean; +}; +export type CreateConnectionApiResponse = /** status 200 OK */ + | Connection + | /** status 201 Created */ Connection + | /** status 202 Accepted */ Connection; +export type CreateConnectionApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + connection: Connection; +}; +export type DeletecollectionConnectionApiResponse = /** status 200 OK */ Status; +export type DeletecollectionConnectionApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string; + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string; + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string; + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean; + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number; +}; +export type GetConnectionApiResponse = /** status 200 OK */ Connection; +export type GetConnectionApiArg = { + /** name of the Connection */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceConnectionApiResponse = /** status 200 OK */ Connection | /** status 201 Created */ Connection; +export type ReplaceConnectionApiArg = { + /** name of the Connection */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + connection: Connection; +}; +export type DeleteConnectionApiResponse = /** status 200 OK */ Status | /** status 202 Accepted */ Status; +export type DeleteConnectionApiArg = { + /** name of the Connection */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** The duration in seconds before the object should be deleted. Value must be non-negative integer. The value zero indicates delete immediately. If this value is nil, the default grace period for the specified type will be used. Defaults to a per object value if not specified. zero means delete immediately. */ + gracePeriodSeconds?: number; + /** if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it */ + ignoreStoreReadErrorWithClusterBreakingPotential?: boolean; + /** Deprecated: please use the PropagationPolicy, this field will be deprecated in 1.7. Should the dependent objects be orphaned. If true/false, the "orphan" finalizer will be added to/removed from the object's finalizers list. Either this field or PropagationPolicy may be set, but not both. */ + orphanDependents?: boolean; + /** Whether and how garbage collection will be performed. Either this field or OrphanDependents may be set, but not both. The default policy is decided by the existing finalizer set in the metadata.finalizers and the resource-specific default policy. Acceptable values are: 'Orphan' - orphan the dependents; 'Background' - allow the garbage collector to delete the dependents in the background; 'Foreground' - a cascading policy that deletes all dependents in the foreground. */ + propagationPolicy?: string; +}; +export type UpdateConnectionApiResponse = /** status 200 OK */ Connection | /** status 201 Created */ Connection; +export type UpdateConnectionApiArg = { + /** name of the Connection */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; +export type GetConnectionRepositoriesApiResponse = /** status 200 OK */ { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + items: any[]; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + metadata?: any; +}; +export type GetConnectionRepositoriesApiArg = { + /** name of the ExternalRepositoryList */ + name: string; +}; +export type GetConnectionStatusApiResponse = /** status 200 OK */ Connection; +export type GetConnectionStatusApiArg = { + /** name of the Connection */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; +}; +export type ReplaceConnectionStatusApiResponse = /** status 200 OK */ Connection | /** status 201 Created */ Connection; +export type ReplaceConnectionStatusApiArg = { + /** name of the Connection */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + connection: Connection; +}; +export type UpdateConnectionStatusApiResponse = /** status 200 OK */ Connection | /** status 201 Created */ Connection; +export type UpdateConnectionStatusApiArg = { + /** name of the Connection */ + name: string; + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string; + /** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */ + dryRun?: string; + /** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */ + fieldManager?: string; + /** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */ + fieldValidation?: string; + /** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */ + force?: boolean; + patch: Patch; +}; export type ListJobApiResponse = /** status 200 OK */ JobList; export type ListJobApiArg = { /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ @@ -1053,6 +1421,169 @@ export type ObjectMeta = { Populated by the system. Read-only. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ uid?: string; }; +export type InlineSecureValue = + | { + /** Create a secure value -- this is only used for POST/PUT */ + create?: string; + /** Name in the secret service (reference) */ + name: string; + /** Remove this value from the secure value map Values owned by this resource will be deleted if necessary */ + remove?: boolean; + } + | { + /** Create a secure value -- this is only used for POST/PUT */ + create: string; + /** Name in the secret service (reference) */ + name?: string; + /** Remove this value from the secure value map Values owned by this resource will be deleted if necessary */ + remove?: boolean; + } + | { + /** Create a secure value -- this is only used for POST/PUT */ + create?: string; + /** Name in the secret service (reference) */ + name?: string; + /** Remove this value from the secure value map Values owned by this resource will be deleted if necessary */ + remove: boolean; + }; +export type ConnectionSecure = { + /** ClientSecret is the reference to the secret used for other providers authentication, and Github on-behalf-of authentication. This value is stored securely and cannot be read back */ + clientSecret?: InlineSecureValue; + /** PrivateKey is the reference to the private key used for GitHub App authentication. This value is stored securely and cannot be read back */ + privateKey?: InlineSecureValue; + /** Token is the reference of the token used to act as the Connection. This value is stored securely and cannot be read back */ + token?: InlineSecureValue; +}; +export type BitbucketConnectionConfig = { + /** App client ID */ + clientID: string; +}; +export type GitHubConnectionConfig = { + /** GitHub App ID */ + appID: string; + /** GitHub App installation ID */ + installationID: string; +}; +export type GitlabConnectionConfig = { + /** App client ID */ + clientID: string; +}; +export type ConnectionSpec = { + /** Bitbucket connection configuration Only applicable when provider is "bitbucket" */ + bitbucket?: BitbucketConnectionConfig; + /** GitHub connection configuration Only applicable when provider is "github" */ + github?: GitHubConnectionConfig; + /** Gitlab connection configuration Only applicable when provider is "gitlab" */ + gitlab?: GitlabConnectionConfig; + /** The connection provider type + + Possible enum values: + - `"bitbucket"` + - `"github"` + - `"gitlab"` */ + type: 'bitbucket' | 'github' | 'gitlab'; + /** The connection URL */ + url?: string; +}; +export type HealthStatus = { + /** When the health was checked last time */ + checked?: number; + /** The type of the error + + Possible enum values: + - `"health"` + - `"hook"` */ + error?: 'health' | 'hook'; + /** When not healthy, requests will not be executed */ + healthy: boolean; + /** Summary messages (can be shown to users) Will only be populated when not healthy */ + message?: string[]; +}; +export type ConnectionStatus = { + /** The connection health status */ + health: HealthStatus; + /** The generation of the spec last time reconciliation ran */ + observedGeneration: number; + /** Connection state + + Possible enum values: + - `"connected"` + - `"disconnected"` */ + state: 'connected' | 'disconnected'; +}; +export type Connection = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + metadata?: ObjectMeta; + secure?: ConnectionSecure; + spec?: ConnectionSpec; + status?: ConnectionStatus; +}; +export type ListMeta = { + /** continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message. */ + continue?: string; + /** remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact. */ + remainingItemCount?: number; + /** String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency */ + resourceVersion?: string; + /** Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. */ + selfLink?: string; +}; +export type ConnectionList = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + items: Connection[]; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + metadata?: ListMeta; +}; +export type StatusCause = { + /** The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional. + + Examples: + "name" - the field "name" on the current resource + "items[0].name" - the field "name" on the first array entry in "items" */ + field?: string; + /** A human-readable description of the cause of the error. This field may be presented as-is to a reader. */ + message?: string; + /** A machine-readable description of the cause of the error. If this value is empty there is no information available. */ + reason?: string; +}; +export type StatusDetails = { + /** The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes. */ + causes?: StatusCause[]; + /** The group attribute of the resource associated with the status StatusReason. */ + group?: string; + /** The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described). */ + name?: string; + /** If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. */ + retryAfterSeconds?: number; + /** UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ + uid?: string; +}; +export type Status = { + /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ + apiVersion?: string; + /** Suggested HTTP return code for this status, 0 if not set. */ + code?: number; + /** Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type. */ + details?: StatusDetails; + /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + kind?: string; + /** A human-readable description of the status of this operation. */ + message?: string; + /** Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ + metadata?: ListMeta; + /** A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it. */ + reason?: string; + /** Status of the operation. One of: "Success" or "Failure". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status */ + status?: string; +}; +export type Patch = object; export type ResourceRef = { /** Group is the group of the resource, such as "dashboard.grafana.app". */ group?: string; @@ -1070,8 +1601,6 @@ export type DeleteJobOptions = { resources?: ResourceRef[]; }; export type MigrateJobOptions = { - /** Preserve history (if possible) */ - history?: boolean; /** Message to use when committing the changes in a single commit */ message?: string; }; @@ -1138,7 +1667,7 @@ export type JobResourceSummary = { delete?: number; /** Create or update (export) */ error?: number; - /** Report errors for this resource type This may not be an exhaustive list and recommend looking at the logs for more info */ + /** Report errors/warnings for this resource type This may not be an exhaustive list and recommend looking at the logs for more info */ errors?: string[]; group?: string; kind?: string; @@ -1146,6 +1675,9 @@ export type JobResourceSummary = { noop?: number; total?: number; update?: number; + /** The error count */ + warning?: number; + warnings?: string[]; write?: number; }; export type RepositoryUrLs = { @@ -1176,6 +1708,7 @@ export type JobStatus = { summary?: JobResourceSummary[]; /** URLs contains URLs for the reference branch or commit if applicable. */ url?: RepositoryUrLs; + warnings?: string[]; }; export type Job = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ @@ -1186,16 +1719,6 @@ export type Job = { spec?: JobSpec; status?: JobStatus; }; -export type ListMeta = { - /** continue may be set if the user set a limit on the number of items returned, and indicates that the server has more data available. The value is opaque and may be used to issue another request to the endpoint that served this list to retrieve the next set of available objects. Continuing a consistent list may not be possible if the server configuration has changed or more than a few minutes have passed. The resourceVersion field returned when using this continue value will be identical to the value in the first response, unless you have received this token from an error message. */ - continue?: string; - /** remainingItemCount is the number of subsequent items in the list which are not included in this list response. If the list request contained label or field selectors, then the number of remaining items is unknown and the field will be left unset and omitted during serialization. If the list is complete (either because it is not chunking or because this is the last chunk), then there are no more remaining items and this field will be left unset and omitted during serialization. Servers older than v1.15 do not set this field. The intended use of the remainingItemCount is *estimating* the size of a collection. Clients should not rely on the remainingItemCount to be set or to be exact. */ - remainingItemCount?: number; - /** String that identifies the server's internal version of this object that can be used by clients to determine when objects have changed. Value must be treated as opaque by clients and passed unmodified back to the server. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency */ - resourceVersion?: string; - /** Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. */ - selfLink?: string; -}; export type JobList = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion?: string; @@ -1204,76 +1727,6 @@ export type JobList = { kind?: string; metadata?: ListMeta; }; -export type StatusCause = { - /** The field of the resource that has caused this error, as named by its JSON serialization. May include dot and postfix notation for nested attributes. Arrays are zero-indexed. Fields may appear more than once in an array of causes due to fields having multiple errors. Optional. - - Examples: - "name" - the field "name" on the current resource - "items[0].name" - the field "name" on the first array entry in "items" */ - field?: string; - /** A human-readable description of the cause of the error. This field may be presented as-is to a reader. */ - message?: string; - /** A machine-readable description of the cause of the error. If this value is empty there is no information available. */ - reason?: string; -}; -export type StatusDetails = { - /** The Causes array includes more details associated with the StatusReason failure. Not all StatusReasons may provide detailed causes. */ - causes?: StatusCause[]; - /** The group attribute of the resource associated with the status StatusReason. */ - group?: string; - /** The kind attribute of the resource associated with the status StatusReason. On some operations may differ from the requested resource Kind. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ - kind?: string; - /** The name attribute of the resource associated with the status StatusReason (when there is a single name which can be described). */ - name?: string; - /** If specified, the time in seconds before the operation should be retried. Some errors may indicate the client must take an alternate action - for those errors this field may indicate how long to wait before taking the alternate action. */ - retryAfterSeconds?: number; - /** UID of the resource. (when there is a single resource which can be described). More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids */ - uid?: string; -}; -export type Status = { - /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ - apiVersion?: string; - /** Suggested HTTP return code for this status, 0 if not set. */ - code?: number; - /** Extended data associated with the reason. Each reason may define its own extended details. This field is optional and the data returned is not guaranteed to conform to any schema except that defined by the reason type. */ - details?: StatusDetails; - /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ - kind?: string; - /** A human-readable description of the status of this operation. */ - message?: string; - /** Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ - metadata?: ListMeta; - /** A machine-readable description of why this operation is in the "Failure" status. If this value is empty there is no information available. A Reason clarifies an HTTP status code but does not override it. */ - reason?: string; - /** Status of the operation. One of: "Success" or "Failure". More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status */ - status?: string; -}; -export type Patch = object; -export type InlineSecureValue = - | { - /** Create a secure value -- this is only used for POST/PUT */ - create?: string; - /** Name in the secret service (reference) */ - name: string; - /** Remove this value from the secure value map Values owned by this resource will be deleted if necessary */ - remove?: boolean; - } - | { - /** Create a secure value -- this is only used for POST/PUT */ - create: string; - /** Name in the secret service (reference) */ - name?: string; - /** Remove this value from the secure value map Values owned by this resource will be deleted if necessary */ - remove?: boolean; - } - | { - /** Create a secure value -- this is only used for POST/PUT */ - create?: string; - /** Name in the secret service (reference) */ - name?: string; - /** Remove this value from the secure value map Values owned by this resource will be deleted if necessary */ - remove: boolean; - }; export type SecureValues = { /** Token used to connect the configured repository */ token?: InlineSecureValue; @@ -1292,6 +1745,9 @@ export type BitbucketRepositoryConfig = { /** The repository URL (e.g. `https://bitbucket.org/example/test`). */ url?: string; }; +export type ConnectionInfo = { + name: string; +}; export type GitRepositoryConfig = { /** The branch to use in the repository. */ branch: string; @@ -1344,6 +1800,8 @@ export type SyncOptions = { export type RepositorySpec = { /** The repository on Bitbucket. Mutually exclusive with local | github | git. */ bitbucket?: BitbucketRepositoryConfig; + /** The connection the repository references. This means the Repository is interacting with git via a Connection. */ + connection?: ConnectionInfo; /** Repository description */ description?: string; /** The repository on Git. Mutually exclusive with local | github | git. */ @@ -1370,20 +1828,6 @@ export type RepositorySpec = { /** UI driven Workflow that allow changes to the contends of the repository. The order is relevant for defining the precedence of the workflows. When empty, the repository does not support any edits (eg, readonly) */ workflows: ('branch' | 'write')[]; }; -export type HealthStatus = { - /** When the health was checked last time */ - checked?: number; - /** The type of the error - - Possible enum values: - - `"health"` - - `"hook"` */ - error?: 'health' | 'hook'; - /** When not healthy, requests will not be executed */ - healthy: boolean; - /** Summary messages (can be shown to users) Will only be populated when not healthy */ - message?: string[]; -}; export type ResourceCount = { count: number; group: string; @@ -1617,8 +2061,6 @@ export type RepositoryViewList = { items: RepositoryView[]; /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ kind?: string; - /** The backend is using legacy storage FIXME: Not sure where this should be exposed... but we need it somewhere The UI should force the onboarding workflow when this is true */ - legacyStorage?: boolean; }; export type ManagerStats = { /** Manager identity */ @@ -1644,6 +2086,21 @@ export type ResourceStats = { export const { useGetApiResourcesQuery, useLazyGetApiResourcesQuery, + useListConnectionQuery, + useLazyListConnectionQuery, + useCreateConnectionMutation, + useDeletecollectionConnectionMutation, + useGetConnectionQuery, + useLazyGetConnectionQuery, + useReplaceConnectionMutation, + useDeleteConnectionMutation, + useUpdateConnectionMutation, + useGetConnectionRepositoriesQuery, + useLazyGetConnectionRepositoriesQuery, + useGetConnectionStatusQuery, + useLazyGetConnectionStatusQuery, + useReplaceConnectionStatusMutation, + useUpdateConnectionStatusMutation, useListJobQuery, useLazyListJobQuery, useCreateJobMutation, diff --git a/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/baseAPI.ts b/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/baseAPI.ts new file mode 100644 index 00000000000..34762fa1b86 --- /dev/null +++ b/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/baseAPI.ts @@ -0,0 +1,16 @@ +import { createApi } from '@reduxjs/toolkit/query/react'; + +import { getAPIBaseURL } from '../../../../utils/utils'; +import { createBaseQuery } from '../../createBaseQuery'; + +export const API_GROUP = 'rules.alerting.grafana.app' as const; +export const API_VERSION = 'v0alpha1' as const; +export const BASE_URL = getAPIBaseURL(API_GROUP, API_VERSION); + +export const api = createApi({ + reducerPath: 'rulesAlertingAPIv0alpha1', + baseQuery: createBaseQuery({ + baseURL: BASE_URL, + }), + endpoints: () => ({}), +}); diff --git a/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/rules.api.gen.ts b/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/endpoints.gen.ts similarity index 98% rename from packages/grafana-alerting/src/grafana/api/rules/v0alpha1/rules.api.gen.ts rename to packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/endpoints.gen.ts index 361362d5699..cfd62d68def 100644 --- a/packages/grafana-alerting/src/grafana/api/rules/v0alpha1/rules.api.gen.ts +++ b/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/endpoints.gen.ts @@ -1,4 +1,4 @@ -import { api } from './api'; +import { api } from './baseAPI'; export const addTagTypes = ['API Discovery', 'AlertRule', 'RecordingRule'] as const; const injectedRtkApi = api .enhanceEndpoints({ @@ -7,7 +7,7 @@ const injectedRtkApi = api .injectEndpoints({ endpoints: (build) => ({ getApiResources: build.query({ - query: () => ({ url: `/apis/rules.alerting.grafana.app/v0alpha1/` }), + query: () => ({ url: `/` }), providesTags: ['API Discovery'], }), listAlertRule: build.query({ @@ -313,7 +313,7 @@ const injectedRtkApi = api }), overrideExisting: false, }); -export { injectedRtkApi as rulesAPI }; +export { injectedRtkApi as generatedAPI }; export type GetApiResourcesApiResponse = /** status 200 OK */ ApiResourceList; export type GetApiResourcesApiArg = void; export type ListAlertRuleApiResponse = /** status 200 OK */ AlertRuleList; @@ -1085,3 +1085,33 @@ export type RecordingRuleList = { kind?: string; metadata: ListMeta; }; +export const { + useGetApiResourcesQuery, + useLazyGetApiResourcesQuery, + useListAlertRuleQuery, + useLazyListAlertRuleQuery, + useCreateAlertRuleMutation, + useDeletecollectionAlertRuleMutation, + useGetAlertRuleQuery, + useLazyGetAlertRuleQuery, + useReplaceAlertRuleMutation, + useDeleteAlertRuleMutation, + useUpdateAlertRuleMutation, + useGetAlertRuleStatusQuery, + useLazyGetAlertRuleStatusQuery, + useReplaceAlertRuleStatusMutation, + useUpdateAlertRuleStatusMutation, + useListRecordingRuleQuery, + useLazyListRecordingRuleQuery, + useCreateRecordingRuleMutation, + useDeletecollectionRecordingRuleMutation, + useGetRecordingRuleQuery, + useLazyGetRecordingRuleQuery, + useReplaceRecordingRuleMutation, + useDeleteRecordingRuleMutation, + useUpdateRecordingRuleMutation, + useGetRecordingRuleStatusQuery, + useLazyGetRecordingRuleStatusQuery, + useReplaceRecordingRuleStatusMutation, + useUpdateRecordingRuleStatusMutation, +} = injectedRtkApi; diff --git a/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/index.ts b/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/index.ts new file mode 100644 index 00000000000..d80fd6d553a --- /dev/null +++ b/packages/grafana-api-clients/src/clients/rtkq/rules.alerting/v0alpha1/index.ts @@ -0,0 +1,5 @@ +export { BASE_URL, API_GROUP, API_VERSION } from './baseAPI'; +import { generatedAPI as rawAPI } from './endpoints.gen'; + +export * from './endpoints.gen'; +export const generatedAPI = rawAPI.enhanceEndpoints({}); diff --git a/packages/grafana-api-clients/src/generator/helpers.ts b/packages/grafana-api-clients/src/generator/helpers.ts index 2ac2ce01389..daba285787c 100644 --- a/packages/grafana-api-clients/src/generator/helpers.ts +++ b/packages/grafana-api-clients/src/generator/helpers.ts @@ -143,8 +143,10 @@ export const updatePackageJsonExports = // Create the new export entry const newExportKey = `./rtkq/${groupName}/${version}`; const newExportValue = { - import: `./src/clients/rtkq/${groupName}/${version}/index.ts`, - require: `./src/clients/rtkq/${groupName}/${version}/index.ts`, + '@grafana-app/source': `./src/clients/rtkq/${groupName}/${version}/index.ts`, + types: `./dist/types/clients/rtkq/${groupName}/${version}/index.d.ts`, + import: `./dist/esm/clients/rtkq/${groupName}/${version}/index.mjs`, + require: `./dist/cjs/clients/rtkq/${groupName}/${version}/index.cjs`, }; // Check if export already exists diff --git a/packages/grafana-api-clients/src/index.ts b/packages/grafana-api-clients/src/index.ts index 96e34be4f87..3fb772884a1 100644 --- a/packages/grafana-api-clients/src/index.ts +++ b/packages/grafana-api-clients/src/index.ts @@ -1 +1,4 @@ export { getAPINamespace, getAPIBaseURL, normalizeError, handleRequestError } from './utils/utils'; + +/* @TODO figure out how to automatically set the MockBackendSrv when consumers of this package write tests using the exported clients */ +export { MockBackendSrv } from './utils/backendSrv.mock'; diff --git a/packages/grafana-api-clients/src/scripts/generate-rtk-apis.ts b/packages/grafana-api-clients/src/scripts/generate-rtk-apis.ts index a353b4e311f..8610da06920 100644 --- a/packages/grafana-api-clients/src/scripts/generate-rtk-apis.ts +++ b/packages/grafana-api-clients/src/scripts/generate-rtk-apis.ts @@ -108,7 +108,10 @@ const config: ConfigFile = { ...createAPIConfig('preferences', 'v1alpha1'), ...createAPIConfig('provisioning', 'v0alpha1'), ...createAPIConfig('shorturl', 'v1beta1'), + ...createAPIConfig('notifications.alerting', 'v0alpha1'), + ...createAPIConfig('rules.alerting', 'v0alpha1'), ...createAPIConfig('historian.alerting', 'v0alpha1'), + ...createAPIConfig('logsdrilldown', 'v1beta1'), ...createAPIConfig('logsdrilldown', 'v1alpha1'), // PLOP_INJECT_API_CLIENT - Used by the API client generator }, diff --git a/packages/grafana-api-clients/src/utils/backendSrv.mock.ts b/packages/grafana-api-clients/src/utils/backendSrv.mock.ts new file mode 100644 index 00000000000..ae7f1129913 --- /dev/null +++ b/packages/grafana-api-clients/src/utils/backendSrv.mock.ts @@ -0,0 +1,46 @@ +import { Observable } from 'rxjs'; +import { fromFetch } from 'rxjs/fetch'; + +import { BackendSrv, BackendSrvRequest, FetchResponse } from '@grafana/runtime'; + +/** + * Minimal mock implementation of BackendSrv for testing. + * Only implements the fetch() method which is used by RTKQ. + * HTTP requests are intercepted by MSW in tests. + */ +export class MockBackendSrv implements Partial { + fetch(options: BackendSrvRequest): Observable> { + const init: RequestInit = { + method: options.method || 'GET', + headers: options.headers, + body: options.data ? JSON.stringify(options.data) : undefined, + credentials: options.credentials, + signal: options.abortSignal, + }; + + return new Observable((observer) => { + fromFetch(options.url, init).subscribe({ + next: async (response) => { + try { + const data = await response.json(); + observer.next({ + data, + status: response.status, + statusText: response.statusText, + ok: response.ok, + headers: response.headers, + redirected: response.redirected, + type: response.type, + url: response.url, + config: options, + }); + observer.complete(); + } catch (error) { + observer.error(error); + } + }, + error: (error) => observer.error(error), + }); + }); + } +} diff --git a/packages/grafana-api-clients/tsconfig.json b/packages/grafana-api-clients/tsconfig.json index ed1c294703e..e75b58104b0 100644 --- a/packages/grafana-api-clients/tsconfig.json +++ b/packages/grafana-api-clients/tsconfig.json @@ -8,7 +8,8 @@ "emitDeclarationOnly": true, "isolatedModules": true, "rootDirs": ["."], - "allowImportingTsExtensions": true + "allowImportingTsExtensions": true, + "moduleResolution": "bundler" }, "exclude": ["dist/**/*"], "include": [ @@ -17,5 +18,12 @@ "../grafana-ui/src/types/*.d.ts", "../grafana-i18n/src/types/*.d.ts", "src/**/*.ts*" - ] + ], + "ts-node": { + "swc": true, + "compilerOptions": { + "module": "es2020", + "moduleResolution": "Bundler" + } + } } diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json index ff90b2c295d..df595973cca 100644 --- a/packages/grafana-data/package.json +++ b/packages/grafana-data/package.json @@ -13,32 +13,31 @@ "url": "http://github.com/grafana/grafana.git", "directory": "packages/grafana-data" }, - "main": "src/index.ts", - "types": "src/index.ts", - "module": "src/index.ts", + "main": "./dist/cjs/index.cjs", + "module": "./dist/esm/index.mjs", + "types": "./dist/types/index.d.ts", "exports": { "./package.json": "./package.json", ".": { - "import": "./src/index.ts", - "require": "./src/index.ts" - }, - "./internal": { - "import": "./src/internal/index.ts", - "require": "./src/internal/index.ts" + "@grafana-app/source": "./src/index.ts", + "types": "./dist/types/index.d.ts", + "import": "./dist/esm/index.mjs", + "require": "./dist/cjs/index.cjs" }, "./unstable": { - "import": "./src/unstable.ts", - "require": "./src/unstable.ts" + "@grafana-app/source": "./src/unstable.ts", + "types": "./dist/types/unstable.d.ts", + "import": "./dist/esm/unstable.mjs", + "require": "./dist/cjs/unstable.cjs" + }, + "./internal": { + "@grafana-app/source": "./src/internal/index.ts" }, "./test": { - "import": "./test/index.ts", - "require": "./test/index.ts" + "@grafana-app/source": "./test/index.ts" } }, "publishConfig": { - "main": "./dist/cjs/index.cjs", - "module": "./dist/esm/index.mjs", - "types": "./dist/types/index.d.ts", "access": "public" }, "files": [ @@ -51,8 +50,8 @@ "build": "tsc -p ./tsconfig.build.json && rollup -c rollup.config.ts --configPlugin esbuild", "clean": "rimraf ./dist ./compiled ./unstable ./package.tgz", "typecheck": "tsc --emitDeclarationOnly false --noEmit", - "prepack": "cp package.json package.json.bak && ALIAS_PACKAGE_NAME=unstable node ../../scripts/prepare-npm-package.js", - "postpack": "mv package.json.bak package.json && rimraf ./unstable" + "prepack": "cp package.json package.json.bak && node ../../scripts/prepare-npm-package.js", + "postpack": "mv package.json.bak package.json" }, "dependencies": { "@braintree/sanitize-url": "7.0.1", diff --git a/packages/grafana-data/rollup.config.ts b/packages/grafana-data/rollup.config.ts index 378ab225769..87008ddc45f 100644 --- a/packages/grafana-data/rollup.config.ts +++ b/packages/grafana-data/rollup.config.ts @@ -9,13 +9,13 @@ export default [ { input: entryPoint, plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-data')], + output: [cjsOutput(pkg, 'grafana-data'), esmOutput(pkg, 'grafana-data')], treeshake: false, }, { input: 'src/unstable.ts', plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-data')], + output: [cjsOutput(pkg, 'grafana-data'), esmOutput(pkg, 'grafana-data')], treeshake: false, }, ]; diff --git a/packages/grafana-data/src/datetime/datemath.test.ts b/packages/grafana-data/src/datetime/datemath.test.ts index f53bbe8e6e5..3abf59ea43f 100644 --- a/packages/grafana-data/src/datetime/datemath.test.ts +++ b/packages/grafana-data/src/datetime/datemath.test.ts @@ -165,9 +165,17 @@ describe('DateMath', () => { expect(date!.valueOf()).toEqual(dateTime([2014, 1, 3]).valueOf()); }); - it('should handle multiple math expressions', () => { - const date = dateMath.parseDateMath('-2d-6h', dateTime([2014, 1, 5])); - expect(date!.valueOf()).toEqual(dateTime([2014, 1, 2, 18]).valueOf()); + it.each([ + ['-2d-6h', [2014, 1, 5], [2014, 1, 2, 18]], + ['-30m-2d', [2014, 1, 5], [2014, 1, 2, 23, 30]], + ['-2d-1d', [2014, 1, 5], [2014, 1, 2]], + ['-1h-30m', [2014, 1, 5, 12, 0], [2014, 1, 5, 10, 30]], + ['-1d-1h-30m', [2014, 1, 5, 12, 0], [2014, 1, 4, 10, 30]], + ['+1d-6h', [2014, 1, 5], [2014, 1, 5, 18]], + ['-1w-1d', [2014, 1, 14], [2014, 1, 6]], + ])('should handle multiple math expressions: %s', (expression, inputDate, expectedDate) => { + const date = dateMath.parseDateMath(expression, dateTime(inputDate)); + expect(date!.valueOf()).toEqual(dateTime(expectedDate).valueOf()); }); it('should return false when invalid expression', () => { diff --git a/packages/grafana-data/src/field/fieldColor.ts b/packages/grafana-data/src/field/fieldColor.ts index 7016c208994..78e0b632619 100644 --- a/packages/grafana-data/src/field/fieldColor.ts +++ b/packages/grafana-data/src/field/fieldColor.ts @@ -9,6 +9,8 @@ import { import stringHash from 'string-hash'; import tinycolor from 'tinycolor2'; +import { t } from '@grafana/i18n'; + import { getContrastRatio } from '../themes/colorManipulator'; import { GrafanaTheme2 } from '../themes/types'; import { reduceField } from '../transformations/fieldReducer'; @@ -30,10 +32,14 @@ export interface FieldColorMode extends RegistryItem { isContinuous?: boolean; isByValue?: boolean; useSeriesName?: boolean; + group?: string; } /** @internal */ export const fieldColorModeRegistry = new Registry(() => { + const accessibleGroup = t('grafana-data.field.fieldColor.accessibleGroup', 'Accessible'); + const otherGroup = t('grafana-data.field.fieldColor.otherGroup', 'Others'); + return [ { id: FieldColorModeId.Fixed, @@ -88,6 +94,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, interpolator: interpolateViridis, + group: accessibleGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousMagma, @@ -95,6 +102,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, interpolator: interpolateMagma, + group: accessibleGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousPlasma, @@ -102,6 +110,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, interpolator: interpolatePlasma, + group: accessibleGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousInferno, @@ -109,6 +118,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, interpolator: interpolateInferno, + group: accessibleGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousCividis, @@ -116,6 +126,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, interpolator: interpolateCividis, + group: accessibleGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousGrYlRd, @@ -123,6 +134,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['green', 'yellow', 'red'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousRdYlGr, @@ -130,6 +142,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['red', 'yellow', 'green'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousBlYlRd, @@ -137,6 +150,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['dark-blue', 'super-light-yellow', 'dark-red'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousYlRd, @@ -144,6 +158,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['super-light-yellow', 'dark-red'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousBlPu, @@ -151,6 +166,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['blue', 'purple'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousYlBl, @@ -158,6 +174,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['super-light-yellow', 'dark-blue'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousBlues, @@ -165,6 +182,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-blue'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousReds, @@ -172,6 +190,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-red'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousGreens, @@ -179,6 +198,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-green'], + group: otherGroup, }), new FieldColorSchemeMode({ id: FieldColorModeId.ContinuousPurples, @@ -186,6 +206,7 @@ export const fieldColorModeRegistry = new Registry(() => { isContinuous: true, isByValue: true, getColors: (theme: GrafanaTheme2) => ['panel-bg', 'dark-purple'], + group: otherGroup, }), ]; }); @@ -197,6 +218,7 @@ interface BaseFieldColorSchemeModeOptions { isContinuous: boolean; isByValue: boolean; useSeriesName?: boolean; + group?: string; } interface FieldColorSchemeModeInterpolator extends BaseFieldColorSchemeModeOptions { @@ -222,6 +244,7 @@ export class FieldColorSchemeMode implements FieldColorMode { colorCacheTheme?: GrafanaTheme2; interpolator?: (value: number) => string; getNamedColors?: (theme: GrafanaTheme2) => string[]; + group?: string; constructor(options: FieldColorSchemeModeOptions) { this.id = options.id; @@ -232,6 +255,7 @@ export class FieldColorSchemeMode implements FieldColorMode { this.isByValue = options.isByValue; this.useSeriesName = options.useSeriesName; this.interpolator = options.interpolator; + this.group = options.group; } getColors(theme: GrafanaTheme2): string[] { diff --git a/packages/grafana-data/src/field/fieldDisplay.test.ts b/packages/grafana-data/src/field/fieldDisplay.test.ts index 718c0e54430..5ec3ed7ba4f 100644 --- a/packages/grafana-data/src/field/fieldDisplay.test.ts +++ b/packages/grafana-data/src/field/fieldDisplay.test.ts @@ -3,11 +3,18 @@ import { merge } from 'lodash'; import { toDataFrame } from '../dataframe/processDataFrame'; import { createTheme } from '../themes/createTheme'; import { ReducerID } from '../transformations/fieldReducer'; +import { FieldType } from '../types/dataFrame'; import { FieldConfigPropertyItem } from '../types/fieldOverrides'; import { MappingType, SpecialValueMatch, ValueMapping } from '../types/valueMapping'; import { getDisplayProcessor } from './displayProcessor'; -import { fixCellTemplateExpressions, getFieldDisplayValues, GetFieldDisplayValuesOptions } from './fieldDisplay'; +import { + FieldSparkline, + fixCellTemplateExpressions, + getFieldDisplayValues, + GetFieldDisplayValuesOptions, + getSparklineHighlight, +} from './fieldDisplay'; import { standardFieldConfigEditorRegistry } from './standardFieldConfigEditorRegistry'; describe('FieldDisplay', () => { @@ -556,3 +563,71 @@ describe('fixCellTemplateExpressions', () => { ); }); }); + +describe('getSparklineHighlight', () => { + const sparkline: FieldSparkline = { + y: { name: 'A', type: FieldType.number, values: [null, 2, 3, 4, 10, 8, 8, 8, 9, null], config: {} }, + }; + + it.each([ + { + calc: ReducerID.last, + expected: { + type: 'point', + xIdx: 9, + }, + }, + { + calc: ReducerID.max, + expected: { + type: 'point', + xIdx: 4, + }, + }, + { + calc: ReducerID.min, + expected: { + type: 'point', + xIdx: 1, + }, + }, + { + calc: ReducerID.first, + expected: { + type: 'point', + xIdx: 0, + }, + }, + { + calc: ReducerID.firstNotNull, + expected: { + type: 'point', + xIdx: 1, + }, + }, + { + calc: ReducerID.lastNotNull, + expected: { + type: 'point', + xIdx: 8, + }, + }, + { + calc: ReducerID.mean, + expected: { + type: 'line', + y: 6.5, + }, + }, + { + calc: ReducerID.median, + expected: { + type: 'line', + y: 8, + }, + }, + ])('it calculates the correct highlight for the $calc', ({ calc, expected }) => { + const result = getSparklineHighlight(sparkline, calc); + expect(result).toEqual(expected); + }); +}); diff --git a/packages/grafana-data/src/field/fieldDisplay.ts b/packages/grafana-data/src/field/fieldDisplay.ts index c4423173da3..3496f419395 100644 --- a/packages/grafana-data/src/field/fieldDisplay.ts +++ b/packages/grafana-data/src/field/fieldDisplay.ts @@ -3,7 +3,7 @@ import { isEmpty } from 'lodash'; import { DataFrameView } from '../dataframe/DataFrameView'; import { getTimeField } from '../dataframe/processDataFrame'; import { GrafanaTheme2 } from '../themes/types'; -import { reduceField, ReducerID } from '../transformations/fieldReducer'; +import { isReducerID, reduceField, ReducerID } from '../transformations/fieldReducer'; import { getFieldMatcher } from '../transformations/matchers'; import { FieldMatcherID } from '../transformations/matchers/ids'; import { ScopedVars } from '../types/ScopedVars'; @@ -43,6 +43,7 @@ export interface FieldSparkline { x?: Field; // if this does not exist, use the index timeRange?: TimeRange; // Optionally force an absolute time highlightIndex?: number; + highlightLine?: number; } export interface FieldDisplay { @@ -72,6 +73,76 @@ export interface GetFieldDisplayValuesOptions { export const DEFAULT_FIELD_DISPLAY_VALUES_LIMIT = 25; +interface SparklineHighlightPoint { + type: 'point'; + xIdx: number; +} + +interface SparklineHighlightLine { + type: 'line'; + y: number; +} + +export function getSparklineHighlight( + sparkline: FieldSparkline, + calc: ReducerID +): SparklineHighlightPoint | SparklineHighlightLine | void { + switch (calc) { + case ReducerID.last: + return { type: 'point', xIdx: sparkline.y.values.length - 1 }; + case ReducerID.first: + return { type: 'point', xIdx: 0 }; + case ReducerID.lastNotNull: { + for (let k = sparkline.y.values.length - 1; k >= 0; k--) { + const v = sparkline.y.values[k]; + if (v !== null && v !== undefined && !Number.isNaN(v)) { + return { type: 'point', xIdx: k }; + } + } + return; + } + case ReducerID.firstNotNull: { + for (let k = 0; k < sparkline.y.values.length; k++) { + const v = sparkline.y.values[k]; + if (v !== null && v !== undefined && !Number.isNaN(v)) { + return { type: 'point', xIdx: k }; + } + } + return; + } + case ReducerID.min: { + let minIdx = -1; + let prevMin = Infinity; + for (let k = 0; k < sparkline.y.values.length; k++) { + const v = sparkline.y.values[k]; + if (v !== null && v !== undefined && !Number.isNaN(v) && v < prevMin) { + prevMin = v; + minIdx = k; + } + } + return minIdx >= 0 ? { type: 'point', xIdx: minIdx } : undefined; + } + case ReducerID.max: { + let maxIdx = -1; + let prevMax = -Infinity; + for (let k = 0; k < sparkline.y.values.length; k++) { + const v = sparkline.y.values[k]; + if (v !== null && v !== undefined && !Number.isNaN(v) && v > prevMax) { + prevMax = v; + maxIdx = k; + } + } + return maxIdx >= 0 ? { type: 'point', xIdx: maxIdx } : undefined; + } + case ReducerID.mean: + return { type: 'line', y: reduceField({ field: sparkline.y, reducers: [ReducerID.mean] }).mean }; + case ReducerID.median: + return { type: 'line', y: reduceField({ field: sparkline.y, reducers: [ReducerID.median] }).median }; + default: + return; + } +} + export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): FieldDisplay[] => { const { replaceVariables, reduceOptions, timeZone, theme } = options; const calcs = reduceOptions.calcs.length ? reduceOptions.calcs : [ReducerID.last]; @@ -190,10 +261,16 @@ export const getFieldDisplayValues = (options: GetFieldDisplayValuesOptions): Fi y: dataFrame.fields[i], x: timeField, }; - if (calc === ReducerID.last) { - sparkline.highlightIndex = sparkline.y.values.length - 1; - } else if (calc === ReducerID.first) { - sparkline.highlightIndex = 0; + if (isReducerID(calc)) { + const sparklineHighlight = getSparklineHighlight(sparkline, calc); + switch (sparklineHighlight?.type) { + case 'point': + sparkline.highlightIndex = sparklineHighlight.xIdx; + break; + case 'line': + sparkline.highlightLine = sparklineHighlight.y; + break; + } } } diff --git a/packages/grafana-data/src/field/fieldOverrides.test.ts b/packages/grafana-data/src/field/fieldOverrides.test.ts index 901fc6d8cc2..b0aa271be3f 100644 --- a/packages/grafana-data/src/field/fieldOverrides.test.ts +++ b/packages/grafana-data/src/field/fieldOverrides.test.ts @@ -9,6 +9,7 @@ import { FieldColorModeId } from '../types/fieldColor'; import { FieldConfigPropertyItem, FieldConfigSource } from '../types/fieldOverrides'; import { InterpolateFunction } from '../types/panel'; import { ThresholdsMode } from '../types/thresholds'; +import { MappingType } from '../types/valueMapping'; import { Registry } from '../utils/Registry'; import { locationUtil } from '../utils/location'; import { mockStandardProperties } from '../utils/tests/mockStandardProperties'; @@ -253,7 +254,7 @@ describe('applyFieldOverrides', () => { ], }); - it('will apply field overrides to the fields within the frame', () => { + it('will apply default field overrides to the fields within the frame', () => { const f0 = createDataFrame({ name: 'A', fields: [ @@ -285,6 +286,41 @@ describe('applyFieldOverrides', () => { expect(withOverrides[0].fields[1].values[0].fields[1].state.range.max).toBe(30); }); + it('will apply targeted field overrides to the fields within the frame', () => { + const f0 = createDataFrame({ + name: 'A', + fields: [ + { + name: 'message', + type: FieldType.string, + values: ['foo'], + }, + { + name: 'frame', + type: FieldType.frame, + values: [f0Internal], + }, + ], + }); + const withOverrides = applyFieldOverrides({ + data: [f0], + fieldConfig: { + defaults: {}, + overrides: [ + { + matcher: { id: FieldMatcherID.byName, options: 'frame' }, + properties: [{ id: 'max', value: 30 }], + }, + ], + }, + replaceVariables: (value) => value, + theme: createTheme(), + fieldConfigRegistry: customFieldRegistry, + }); + + expect(withOverrides[0].fields[1].values[0].fields[1].config.max).toBe(30); + }); + it('will not crash when some of the nested frames are undefined', () => { const f0 = createDataFrame({ name: 'A', @@ -964,6 +1000,45 @@ describe('setDynamicConfigValue', () => { expect(config.custom.property3).toEqual({}); expect(config.displayName).toBeUndefined(); }); + + it('works correctly with multiple value mappings in the same override', () => { + const config: FieldConfig = { + mappings: [{ type: MappingType.ValueToText, options: { existing: { text: 'existing' } } }], + }; + + setDynamicConfigValue( + config, + { + id: 'mappings', + value: [{ type: MappingType.ValueToText, options: { first: { text: 'first' } } }], + }, + { + fieldConfigRegistry: customFieldRegistry, + data: [], + field: { type: FieldType.number } as Field, + dataFrameIndex: 0, + } + ); + + setDynamicConfigValue( + config, + { + id: 'mappings', + value: [{ type: MappingType.ValueToText, options: { second: { text: 'second' } } }], + }, + { + fieldConfigRegistry: customFieldRegistry, + data: [], + field: { type: FieldType.number } as Field, + dataFrameIndex: 0, + } + ); + + expect(config.mappings).toHaveLength(3); + expect(config.mappings![0]).toEqual({ type: MappingType.ValueToText, options: { existing: { text: 'existing' } } }); + expect(config.mappings![1]).toEqual({ type: MappingType.ValueToText, options: { first: { text: 'first' } } }); + expect(config.mappings![2]).toEqual({ type: MappingType.ValueToText, options: { second: { text: 'second' } } }); + }); }); describe('getLinksSupplier', () => { diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index 2aac477cd2b..bf56f811106 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -1,4 +1,4 @@ -import { isNumber, set, unset, get, cloneDeep } from 'lodash'; +import { isNumber, set, unset, get, cloneDeep, defaultsDeep } from 'lodash'; import { createContext, useContext, useMemo, useRef } from 'react'; import { usePrevious } from 'react-use'; @@ -240,9 +240,14 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra ...options, // nested frames can be `undefined` in certain situations, like after `merge` transform due to padding the value array. // let's replace them with empty frames to avoid errors applying overrides - data: field.values.map( - (nestedFrame: DataFrame | undefined): DataFrame => nestedFrame ?? createDataFrame({ fields: [] }) - ), + data: field.values.map((nestedFrame: DataFrame | undefined): DataFrame => { + const result = nestedFrame ?? createDataFrame({ fields: [] }); + result.fields = result.fields.map((newField) => { + newField.config = defaultsDeep(newField.config || {}, config); + return newField; + }); + return result; + }), }); } } @@ -256,7 +261,7 @@ function calculateRange( field: Field, globalRange: NumericRange | undefined, data: DataFrame[] -): { range?: { min?: number | null; max?: number | null; delta: number }; newGlobalRange: NumericRange | undefined } { +): { range?: NumericRange; newGlobalRange?: NumericRange } { // If range is defined with min/max, use it if (isNumber(config.min) && isNumber(config.max)) { const range = { min: config.min, max: config.max, delta: config.max - config.min }; @@ -336,7 +341,7 @@ export function setDynamicConfigValue(config: FieldConfig, value: DynamicConfigV return; } - const val = item.process(value.value, context, item.settings); + let val = item.process(value.value, context, item.settings); const remove = val === undefined || val === null; @@ -347,6 +352,15 @@ export function setDynamicConfigValue(config: FieldConfig, value: DynamicConfigV unset(config, item.path); } } else { + // Merge arrays (e.g. mappings) when multiple overrides target the same field + if (Array.isArray(val)) { + const existingValue = item.isCustom ? get(config.custom, item.path) : get(config, item.path); + + if (Array.isArray(existingValue)) { + val = [...existingValue, ...val]; + } + } + if (item.isCustom) { if (!config.custom) { config.custom = {}; diff --git a/packages/grafana-data/src/index.ts b/packages/grafana-data/src/index.ts index 5084c577176..6027b566764 100644 --- a/packages/grafana-data/src/index.ts +++ b/packages/grafana-data/src/index.ts @@ -521,6 +521,7 @@ export { VariableRefresh, VariableSort, VariableHide, + type VariableRegexApplyTo, type VariableType, type VariableModel, type TypedVariableModel, @@ -663,6 +664,7 @@ export { type DataSourceGetTagKeysOptions, type DataSourceGetTagValuesOptions, type DataSourceGetDrilldownsApplicabilityOptions, + type DataSourceGetRecommendedDrilldownsOptions, type MetadataInspectorProps, type LegacyMetricFindQueryOptions, type QueryEditorProps, @@ -680,6 +682,7 @@ export { type QueryHint, type MetricFindValue, type DrilldownsApplicability, + type DrilldownRecommendation, type DataSourceJsonData, type DataSourceSettings, type DataSourceInstanceSettings, diff --git a/packages/grafana-data/src/transformations/transformers/ids.ts b/packages/grafana-data/src/transformations/transformers/ids.ts index cc2b76fae69..a3d5536c670 100644 --- a/packages/grafana-data/src/transformations/transformers/ids.ts +++ b/packages/grafana-data/src/transformations/transformers/ids.ts @@ -42,5 +42,6 @@ export enum DataTransformerID { formatTime = 'formatTime', formatString = 'formatString', regression = 'regression', + smoothing = 'smoothing', groupToNestedTable = 'groupToNestedTable', } diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts index f519b1d56b4..b2d3c16a3b1 100644 --- a/packages/grafana-data/src/types/config.ts +++ b/packages/grafana-data/src/types/config.ts @@ -289,6 +289,7 @@ export interface GrafanaConfig { rudderstackWriteKey: string; rudderstackDataPlaneUrl: string; rudderstackSdkUrl: string; + rudderstackV3SdkUrl: string; rudderstackConfigUrl: string; rudderstackIntegrationsUrl: string; applicationInsightsConnectionString: string; diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 538e7a051e8..f50e126a5c7 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -313,6 +313,13 @@ abstract class DataSourceApi< options?: DataSourceGetDrilldownsApplicabilityOptions ): Promise; + /** + * Get recommended drilldowns for a dashboard + */ + getRecommendedDrilldowns?( + options?: DataSourceGetRecommendedDrilldownsOptions + ): Promise; + /** * Get tag keys for adhoc filters */ @@ -398,13 +405,9 @@ abstract class DataSourceApi< } /** - * Options argument to DataSourceAPI.getTagKeys + * Base options shared across datasource filtering operations. */ -export interface DataSourceGetTagKeysOptions { - /** - * The other existing filters or base filters. New in v10.3 - */ - filters: AdHocVariableFilter[]; +export interface DataSourceFilteringRequestOptions { /** * Context time range. New in v10.3 */ @@ -413,21 +416,27 @@ export interface DataSourceGetTagKeysOptions + extends DataSourceFilteringRequestOptions { + /** + * The other existing filters or base filters. New in v10.3 + */ + filters: AdHocVariableFilter[]; +} + /** * Options argument to DataSourceAPI.getTagValues */ -export interface DataSourceGetTagValuesOptions { +export interface DataSourceGetTagValuesOptions + extends DataSourceFilteringRequestOptions { key: string; /** * The other existing filters or base filters. New in v10.3 */ filters: AdHocVariableFilter[]; - /** - * Context time range. New in v10.3 - */ - timeRange?: TimeRange; - queries?: TQuery[]; - scopes?: Scope[] | undefined; } export interface MetadataInspectorProps< @@ -646,12 +655,22 @@ export interface MetricFindValue { properties?: Record; } -export interface DataSourceGetDrilldownsApplicabilityOptions { +export interface DataSourceGetDrilldownsApplicabilityOptions + extends DataSourceFilteringRequestOptions { + filters?: AdHocVariableFilter[]; + groupByKeys?: string[]; +} + +export interface DataSourceGetRecommendedDrilldownsOptions + extends DataSourceFilteringRequestOptions { + dashboardUid?: string; + filters?: AdHocVariableFilter[]; + groupByKeys?: string[]; +} + +export interface DrilldownRecommendation { filters?: AdHocVariableFilter[]; groupByKeys?: string[]; - timeRange?: TimeRange; - queries?: TQuery[]; - scopes?: Scope[] | undefined; } export interface DrilldownsApplicability { diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 3fab1ac8bd5..f1b1ce4154d 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -126,11 +126,6 @@ export interface FeatureToggles { */ disableSSEDataplane?: boolean; /** - * Writes error logs to the request logger - * @default true - */ - unifiedRequestLog?: boolean; - /** * Uses JWT-based auth for rendering instead of relying on remote cache */ renderAuthJWT?: boolean; @@ -212,6 +207,10 @@ export interface FeatureToggles { */ reportingRetries?: boolean; /** + * Enables CSV encoding options in the reporting feature + */ + reportingCsvEncodingOptions?: boolean; + /** * Send query to the same datasource in a single request when using server side expressions. The `cloudWatchBatchQueries` feature toggle should be enabled if this used with CloudWatch. */ sseGroupByDatasource?: boolean; @@ -261,6 +260,10 @@ export interface FeatureToggles { */ kubernetesCorrelations?: boolean; /** + * Adds support for Kubernetes unified storage quotas + */ + kubernetesUnifiedStorageQuotas?: boolean; + /** * Adds support for Kubernetes logs drilldown */ kubernetesLogsDrilldown?: boolean; @@ -305,10 +308,6 @@ export interface FeatureToggles { */ queryServiceFromUI?: boolean; /** - * Routes explore requests to the new query service - */ - queryServiceFromExplore?: boolean; - /** * Runs CloudWatch metrics queries as separate batches */ cloudWatchBatchQueries?: boolean; @@ -361,10 +360,6 @@ export interface FeatureToggles { */ dashboardNewLayouts?: boolean; /** - * Use the v2 kubernetes API in the frontend for dashboards - */ - kubernetesDashboardsV2?: boolean; - /** * Enables undo/redo in dynamic dashboards */ dashboardUndoRedo?: boolean; @@ -373,14 +368,22 @@ export interface FeatureToggles { */ unlimitedLayoutsNesting?: boolean; /** + * Enables showing recently used drilldowns or recommendations given by the datasource in the AdHocFilters and GroupBy variables + */ + drilldownRecommendations?: boolean; + /** * Enables viewing non-applicable drilldowns on a panel level */ perPanelNonApplicableDrilldowns?: boolean; /** - * Enabled a group by action per panel + * Enables a group by action per panel */ panelGroupBy?: boolean; /** + * Enables filtering by grouping labels on the panel level through legend or tooltip + */ + perPanelFiltering?: boolean; + /** * Enables use of the `systemPanelFilterVar` variable to filter panels in a dashboard */ panelFilterVariable?: boolean; @@ -401,10 +404,6 @@ export interface FeatureToggles { */ tableSharedCrosshair?: boolean; /** - * Use the kubernetes API for feature toggle management in the frontend - */ - kubernetesFeatureToggles?: boolean; - /** * Enabled grafana cloud specific RBAC roles */ cloudRBACRoles?: boolean; @@ -418,6 +417,10 @@ export interface FeatureToggles { */ jitterAlertRulesWithinGroups?: boolean; /** + * Enable audit logging with Kubernetes under app platform + */ + auditLoggingAppPlatform?: boolean; + /** * Enable the secrets management API and services under app platform */ secretsManagementAppPlatform?: boolean; @@ -491,6 +494,10 @@ export interface FeatureToggles { */ newDashboardWithFiltersAndGroupBy?: boolean; /** + * Wraps the ad hoc and group by variables in a single wrapper, with all other variables below it + */ + dashboardAdHocAndGroupByWrapper?: boolean; + /** * Updates CloudWatch label parsing to be more accurate * @default true */ @@ -520,14 +527,14 @@ export interface FeatureToggles { */ dashboardTemplates?: boolean; /** - * Sets the logs table as default visualisation in logs explore - */ - logsExploreTableDefaultVisualization?: boolean; - /** * Enables the new alert list view design */ alertingListViewV2?: boolean; /** + * Enables saved searches for alert rules list + */ + alertingSavedSearches?: boolean; + /** * Disables the ability to send alerts to an external Alertmanager datasource. */ alertingDisableSendAlertsExternal?: boolean; @@ -615,10 +622,6 @@ export interface FeatureToggles { */ exploreLogsAggregatedMetrics?: boolean; /** - * Used in Logs Drilldown to limit the time range - */ - exploreLogsLimitedTimeRange?: boolean; - /** * Enables the gRPC client to authenticate with the App Platform by using ID & access tokens */ appPlatformGrpcClientAuth?: boolean; @@ -646,10 +649,6 @@ export interface FeatureToggles { */ rolePickerDrawer?: boolean; /** - * Enable unified storage search - */ - unifiedStorageSearch?: boolean; - /** * Enable sprinkles on unified storage search */ unifiedStorageSearchSprinkles?: boolean; @@ -692,10 +691,6 @@ export interface FeatureToggles { */ passwordlessMagicLinkAuthentication?: boolean; /** - * Display Related Logs in Grafana Metrics Drilldown - */ - exploreMetricsRelatedLogs?: boolean; - /** * Adds support for quotes and special characters in label values for Prometheus queries */ prometheusSpecialCharsInLabelValues?: boolean; @@ -771,20 +766,11 @@ export interface FeatureToggles { */ elasticsearchCrossClusterSearch?: boolean; /** - * Displays the navigation history so the user can navigate back to previous pages - */ - unifiedHistory?: boolean; - /** * Defaults to using the Loki `/labels` API instead of `/series` * @default true */ lokiLabelNamesQueryApi?: boolean; /** - * Enable the investigations backend API - * @default false - */ - investigationsBackend?: boolean; - /** * Enable folder's api server counts * @default false */ @@ -820,6 +806,10 @@ export interface FeatureToggles { */ fetchRulesUsingPost?: boolean; /** + * Add compact=true when fetching rules + */ + fetchRulesInCompactMode?: boolean; + /** * Enables the new logs panel * @default true */ @@ -951,7 +941,8 @@ export interface FeatureToggles { */ alertingBulkActionsInUI?: boolean; /** - * Registers AuthZ /apis endpoint + * Deprecated: Use kubernetesAuthzCoreRolesApi, kubernetesAuthzRolesApi, and kubernetesAuthzRoleBindingsApi instead + * @deprecated */ kubernetesAuthzApis?: boolean; /** @@ -967,6 +958,18 @@ export interface FeatureToggles { */ kubernetesAuthzZanzanaSync?: boolean; /** + * Registers AuthZ Core Roles /apis endpoint + */ + kubernetesAuthzCoreRolesApi?: boolean; + /** + * Registers AuthZ Roles /apis endpoint + */ + kubernetesAuthzRolesApi?: boolean; + /** + * Registers AuthZ Role Bindings /apis endpoint + */ + kubernetesAuthzRoleBindingsApi?: boolean; + /** * Enables create, delete, and update mutations for resources owned by IAM identity */ kubernetesAuthnMutation?: boolean; @@ -980,6 +983,11 @@ export interface FeatureToggles { */ restoreDashboards?: boolean; /** + * Enables recently viewed dashboards section in the browsing dashboard page + * @default false + */ + recentlyViewedDashboards?: boolean; + /** * Enable configuration of alert enrichments in Grafana Cloud. * @default false */ @@ -1113,11 +1121,6 @@ export interface FeatureToggles { */ pluginContainers?: boolean; /** - * Run search queries through the tempo backend - * @default false - */ - tempoSearchBackendMigration?: boolean; - /** * Prioritize loading plugins from the CDN before other sources * @default false */ @@ -1148,6 +1151,11 @@ export interface FeatureToggles { */ externalVizSuggestions?: boolean; /** + * Enable Y-axis scale configuration options for pre-bucketed heatmap data (heatmap-rows) + * @default false + */ + heatmapRowsAxisOptions?: boolean; + /** * Restrict PanelChrome contents with overflow: hidden; * @default true */ @@ -1172,10 +1180,20 @@ export interface FeatureToggles { */ onlyStoreActionSets?: boolean; /** + * Show insights for plugins in the plugin details page + * @default false + */ + pluginInsights?: boolean; + /** * Enables a new panel time settings drawer */ panelTimeSettings?: boolean; /** + * Enables the raw DSL query editor in the Elasticsearch data source + * @default false + */ + elasticsearchRawDSLQuery?: boolean; + /** * Enables app platform API for annotations * @default false */ @@ -1216,4 +1234,20 @@ export interface FeatureToggles { * @default false */ useMTPlugins?: boolean; + /** + * Enables support for variables whose values can have multiple properties + */ + multiPropsVariables?: boolean; + /** + * Enables the ASAP smoothing transformation for time series data + */ + smoothingTransformation?: boolean; + /** + * Enables the creation of keepers that manage secrets stored on AWS secrets manager + */ + secretsManagementAppPlatformAwsKeeper?: boolean; + /** + * Enables profiles exemplars support in profiles drilldown + */ + profilesExemplars?: boolean; } diff --git a/packages/grafana-data/src/types/icon.ts b/packages/grafana-data/src/types/icon.ts index b49be0d5363..3dc7215a2cf 100644 --- a/packages/grafana-data/src/types/icon.ts +++ b/packages/grafana-data/src/types/icon.ts @@ -52,6 +52,7 @@ export const availableIconsIndex = { bookmark: true, 'book-open': true, 'brackets-curly': true, + brain: true, 'browser-alt': true, bug: true, building: true, @@ -288,6 +289,7 @@ export const availableIconsIndex = { bitbucket: true, git: true, 'tachometer-fast': true, + 'tachometer-empty': true, 'cmab-logo': true, }; diff --git a/packages/grafana-data/src/types/logs.ts b/packages/grafana-data/src/types/logs.ts index 94f1d97518c..b5e66d705f4 100644 --- a/packages/grafana-data/src/types/logs.ts +++ b/packages/grafana-data/src/types/logs.ts @@ -273,7 +273,7 @@ export interface DataSourceWithSupplementaryQueriesSupport): SupplementaryQueryType[]; /** * Returns a supplementary query to be used to fetch supplementary data based on the provided type and original query. * If the provided query is not suitable for the provided supplementary query type, undefined should be returned. @@ -283,7 +283,8 @@ export interface DataSourceWithSupplementaryQueriesSupport( datasource: DataSourceApi | (DataSourceApi & DataSourceWithSupplementaryQueriesSupport), - type: SupplementaryQueryType + type: SupplementaryQueryType, + dsRequest?: DataQueryRequest ): datasource is DataSourceApi & DataSourceWithSupplementaryQueriesSupport => { if (!datasource) { return false; @@ -293,7 +294,7 @@ export const hasSupplementaryQuerySupport = ( ('getDataProvider' in datasource || 'getSupplementaryRequest' in datasource) && 'getSupplementaryQuery' in datasource && 'getSupportedSupplementaryQueryTypes' in datasource && - datasource.getSupportedSupplementaryQueryTypes().includes(type) + datasource.getSupportedSupplementaryQueryTypes(dsRequest).includes(type) ); }; diff --git a/packages/grafana-data/src/types/pluginExtensions.ts b/packages/grafana-data/src/types/pluginExtensions.ts index 40d20b88c38..cc2a97b4a50 100644 --- a/packages/grafana-data/src/types/pluginExtensions.ts +++ b/packages/grafana-data/src/types/pluginExtensions.ts @@ -30,6 +30,7 @@ export type PluginExtensionLink = PluginExtensionBase & { onClick?: (event?: React.MouseEvent) => void; icon?: IconName; category?: string; + openInNewTab?: boolean; }; export type PluginExtensionComponentMeta = Omit; @@ -86,6 +87,7 @@ export type PluginExtensionAddedComponentConfig = PluginExtensionCon */ component: React.ComponentType; }; + export type PluginExtensionAddedFunctionConfig = PluginExtensionConfigBase & { /** * The target extension points where the component will be added @@ -106,6 +108,7 @@ export type PluginAddedLinksConfigureFunc = (context: Re onClick: (event: React.MouseEvent | undefined, helpers: PluginExtensionEventHelpers) => void; icon: IconName; category: string; + openInNewTab: boolean; }> | undefined; @@ -137,6 +140,10 @@ export type PluginExtensionAddedLinkConfig = Pl // (Optional) A category to be used when grouping the options in the ui category?: string; + + // (Optional) If true, opens the link in a new tab (renders with target="_blank") + // (Important: this is not guaranteed, depends on the extension point if it implements it.) + openInNewTab?: boolean; }; export type PluginExtensionExposedComponentConfig = PluginExtensionConfigBase & { diff --git a/packages/grafana-data/src/types/templateVars.ts b/packages/grafana-data/src/types/templateVars.ts index e6feea4dd3f..62ce2862af2 100644 --- a/packages/grafana-data/src/types/templateVars.ts +++ b/packages/grafana-data/src/types/templateVars.ts @@ -32,6 +32,8 @@ export enum VariableRefresh { onTimeRangeChanged, } +export type VariableRegexApplyTo = 'value' | 'text'; + export enum VariableSort { disabled, alphabeticalAsc, @@ -101,6 +103,7 @@ export interface IntervalVariableModel extends VariableWithOptions { export interface CustomVariableModel extends VariableWithMultiSupport { type: 'custom'; + valuesFormat?: 'csv' | 'json'; } export interface DataSourceVariableModel extends VariableWithMultiSupport { @@ -117,6 +120,7 @@ export interface QueryVariableModel extends VariableWithMultiSupport { queryValue?: string; query: any; regex: string; + regexApplyTo?: VariableRegexApplyTo; refresh: VariableRefresh; staticOptions?: VariableOption[]; staticOptionsOrder?: 'before' | 'after' | 'sorted'; diff --git a/packages/grafana-data/tsconfig.json b/packages/grafana-data/tsconfig.json index d13025d3115..8e6013e32d9 100644 --- a/packages/grafana-data/tsconfig.json +++ b/packages/grafana-data/tsconfig.json @@ -3,10 +3,12 @@ "compilerOptions": { "declaration": true, "jsx": "react-jsx", + "baseUrl": "./", "declarationDir": "./dist/types", "emitDeclarationOnly": true, "isolatedModules": true, - "rootDirs": ["."] + "rootDirs": ["."], + "moduleResolution": "bundler" }, "exclude": ["dist/**/*"], "include": [ diff --git a/packages/grafana-e2e-selectors/package.json b/packages/grafana-e2e-selectors/package.json index 0dd5c5a9925..5527f4c0ca6 100644 --- a/packages/grafana-e2e-selectors/package.json +++ b/packages/grafana-e2e-selectors/package.json @@ -16,12 +16,19 @@ "url": "http://github.com/grafana/grafana.git", "directory": "packages/grafana-e2e-selectors" }, - "main": "src/index.ts", - "types": "src/index.ts", + "main": "./dist/cjs/index.cjs", + "module": "./dist/esm/index.mjs", + "types": "./dist/types/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "@grafana-app/source": "./src/index.ts", + "types": "./dist/types/index.d.ts", + "import": "./dist/esm/index.mjs", + "require": "./dist/cjs/index.cjs" + } + }, "publishConfig": { - "main": "./dist/cjs/index.cjs", - "module": "./dist/esm/index.mjs", - "types": "./dist/types/index.d.ts", "access": "public" }, "files": [ diff --git a/packages/grafana-e2e-selectors/rollup.config.ts b/packages/grafana-e2e-selectors/rollup.config.ts index 1d47540a42a..a17799cc9a7 100644 --- a/packages/grafana-e2e-selectors/rollup.config.ts +++ b/packages/grafana-e2e-selectors/rollup.config.ts @@ -9,7 +9,7 @@ export default [ { input: entryPoint, plugins, - output: [cjsOutput(pkg), esmOutput(pkg, 'grafana-e2e-selectors')], + output: [cjsOutput(pkg, 'grafana-e2e-selectors'), esmOutput(pkg, 'grafana-e2e-selectors')], treeshake: false, }, ]; diff --git a/packages/grafana-e2e-selectors/src/index.ts b/packages/grafana-e2e-selectors/src/index.ts index 32b22b5bb52..5b078f1233f 100644 --- a/packages/grafana-e2e-selectors/src/index.ts +++ b/packages/grafana-e2e-selectors/src/index.ts @@ -1,5 +1,5 @@ /** - * A library containing the different design components of the Grafana ecosystem. + * A library containing e2e selectors for the Grafana ecosystem. * * @packageDocumentation */ diff --git a/packages/grafana-e2e-selectors/src/resolver.test.ts b/packages/grafana-e2e-selectors/src/resolver.test.ts index a306f9261ed..888cf4fdc54 100644 --- a/packages/grafana-e2e-selectors/src/resolver.test.ts +++ b/packages/grafana-e2e-selectors/src/resolver.test.ts @@ -51,7 +51,7 @@ describe('Resolver', () => { expect(pages.Alerting.AddAlertRule.url).toBe('/alerting/new'); }); - it('should throw error if an invalid semver range is used in versioned selector', () => { + it('should throw an error if an invalid semver range is used in versioned selector', () => { expect(() => resolveSelectors({ Alerting: { diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index 47c30187175..7dd819a1512 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -3,7 +3,7 @@ // (a ); diff --git a/packages/grafana-ui/src/components/InteractiveTable/types.ts b/packages/grafana-ui/src/components/InteractiveTable/types.ts index 47263d4730e..5b84f4c568b 100644 --- a/packages/grafana-ui/src/components/InteractiveTable/types.ts +++ b/packages/grafana-ui/src/components/InteractiveTable/types.ts @@ -26,4 +26,8 @@ export interface Column { * If the provided function returns `false` the column will be hidden. */ visible?: (data: TableData[]) => boolean; + /** + * Determines starting sort direction when the column header is clicked. + */ + sortDescFirst?: boolean; } diff --git a/packages/grafana-ui/src/components/InteractiveTable/utils.ts b/packages/grafana-ui/src/components/InteractiveTable/utils.ts index 68017bbfd19..050419fe1d1 100644 --- a/packages/grafana-ui/src/components/InteractiveTable/utils.ts +++ b/packages/grafana-ui/src/components/InteractiveTable/utils.ts @@ -1,6 +1,6 @@ import { Column as RTColumn } from 'react-table'; -import { ExpanderCell, ExpanderHeader } from './Expander'; +import { EmptyExpanderHeader, ExpanderCell, ExpanderHeader } from './Expander'; import { Column } from './types'; export const EXPANDER_CELL_ID = '__expander' as const; @@ -18,9 +18,7 @@ export function getColumns( { id: EXPANDER_CELL_ID, Cell: ExpanderCell, - ...(showExpandAll && { - Header: ExpanderHeader, - }), + Header: showExpandAll ? ExpanderHeader : EmptyExpanderHeader, disableSortBy: true, width: 0, }, @@ -35,6 +33,7 @@ export function getColumns( disableSortBy: !Boolean(column.sortType), width: column.disableGrow ? 0 : undefined, visible: column.visible, + ...(column.sortDescFirst !== undefined && { sortDescFirst: column.sortDescFirst }), ...(column.cell && { Cell: column.cell }), })), ]; diff --git a/packages/grafana-ui/src/components/Layout/Grid/Grid.tsx b/packages/grafana-ui/src/components/Layout/Grid/Grid.tsx index ffba1eb88de..2960de1f502 100644 --- a/packages/grafana-ui/src/components/Layout/Grid/Grid.tsx +++ b/packages/grafana-ui/src/components/Layout/Grid/Grid.tsx @@ -28,7 +28,7 @@ interface PropsWithMinColumnWidth extends GridPropsBase { /** For a responsive layout, fit as many columns while maintaining this minimum column width. * The real width will be calculated based on the theme spacing tokens: `theme.spacing(minColumnWidth)` */ - minColumnWidth?: ResponsiveProp<1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 44 | 55 | 72 | 89 | 144>; + minColumnWidth?: ResponsiveProp<1 | 2 | 3 | 5 | 8 | 13 | 16 | 21 | 34 | 44 | 55 | 72 | 89 | 144>; } /** 'columns' and 'minColumnWidth' are mutually exclusive */ diff --git a/packages/grafana-ui/src/components/Modal/Modal.tsx b/packages/grafana-ui/src/components/Modal/Modal.tsx index aaeb2c3e426..f6ea73c3d31 100644 --- a/packages/grafana-ui/src/components/Modal/Modal.tsx +++ b/packages/grafana-ui/src/components/Modal/Modal.tsx @@ -1,9 +1,7 @@ import { cx } from '@emotion/css'; -import { useDialog } from '@react-aria/dialog'; -import { FocusScope } from '@react-aria/focus'; -import { OverlayContainer, useOverlay } from '@react-aria/overlays'; -import { PropsWithChildren, useRef, type JSX } from 'react'; -import * as React from 'react'; +import { FloatingFocusManager, useDismiss, useFloating, useInteractions, useRole } from '@floating-ui/react'; +import { OverlayContainer } from '@react-aria/overlays'; +import { PropsWithChildren, ReactNode, useId, type JSX } from 'react'; import { t } from '@grafana/i18n'; @@ -66,23 +64,26 @@ export function Modal(props: PropsWithChildren) { trapFocus = true, } = props; const styles = useStyles2(getModalStyles); + const titleId = useId(); - const ref = useRef(null); - - // Handle interacting outside the dialog and pressing - // the Escape key to close the modal. - const { overlayProps, underlayProps } = useOverlay( - { isKeyboardDismissDisabled: !closeOnEscape, isOpen, onClose: onDismiss }, - ref - ); - - // Get props for the dialog and its title - const { dialogProps, titleProps } = useDialog( - { - 'aria-label': ariaLabel, + const { context, refs } = useFloating({ + open: isOpen, + onOpenChange: (open) => { + if (!open) { + onDismiss?.(); + } }, - ref - ); + }); + + const dismiss = useDismiss(context, { + enabled: closeOnEscape, + }); + + const role = useRole(context, { + role: 'dialog', + }); + + const { getFloatingProps } = useInteractions([dismiss, role]); if (!isOpen) { return null; @@ -96,12 +97,17 @@ export function Modal(props: PropsWithChildren) { role="presentation" className={styles.modalBackdrop} onClick={onClickBackdrop || (closeOnBackdropClick ? onDismiss : undefined)} - {...underlayProps} /> - -
+ +
- {typeof title === 'string' && } + {typeof title === 'string' && } { // FIXME: custom title components won't get an accessible title. // Do we really want to support them or shall we just limit this ModalTabsHeader? @@ -118,12 +124,12 @@ export function Modal(props: PropsWithChildren) {
{children}
- +
); } -function ModalButtonRow({ leftItems, children }: { leftItems?: React.ReactNode; children: React.ReactNode }) { +function ModalButtonRow({ leftItems, children }: { leftItems?: ReactNode; children: ReactNode }) { const styles = useStyles2(getModalStyles); if (leftItems) { diff --git a/packages/grafana-ui/src/components/Modal/getModalStyles.ts b/packages/grafana-ui/src/components/Modal/getModalStyles.ts index 3c124d24e68..f1e92cfa3f6 100644 --- a/packages/grafana-ui/src/components/Modal/getModalStyles.ts +++ b/packages/grafana-ui/src/components/Modal/getModalStyles.ts @@ -79,7 +79,7 @@ export const getModalStyles = (theme: GrafanaTheme2) => { modalContent: css({ overflow: 'auto', padding: theme.spacing(3, 3, 0, 3), - marginBottom: theme.spacing(3), + marginBottom: theme.spacing(2.5), scrollbarWidth: 'thin', width: '100%', diff --git a/packages/grafana-ui/src/components/PanelChrome/HoverWidget.tsx b/packages/grafana-ui/src/components/PanelChrome/HoverWidget.tsx index eb5c54d7b3b..0660b9a0118 100644 --- a/packages/grafana-ui/src/components/PanelChrome/HoverWidget.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/HoverWidget.tsx @@ -16,17 +16,22 @@ interface Props { title?: string; offset?: number; dragClass?: string; + onDragStart?: (event: React.PointerEvent) => void; onOpenMenu?: () => void; } -export function HoverWidget({ menu, title, dragClass, children, offset = -32, onOpenMenu }: Props) { +export function HoverWidget({ menu, title, dragClass, children, offset = -32, onOpenMenu, onDragStart }: Props) { const styles = useStyles2(getStyles); const draggableRef = useRef(null); const selectors = e2eSelectors.components.Panels.Panel.HoverWidget; // Capture the pointer to keep the widget visible while dragging - const onPointerDown = useCallback((e: React.PointerEvent) => { - draggableRef.current?.setPointerCapture(e.pointerId); - }, []); + const onPointerDown = useCallback( + (e: React.PointerEvent) => { + draggableRef.current?.setPointerCapture(e.pointerId); + onDragStart?.(e); + }, + [onDragStart] + ); const onPointerUp = useCallback((e: React.PointerEvent) => { draggableRef.current?.releasePointerCapture(e.pointerId); diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index 28a395c7d98..f969bbcf3f0 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -248,15 +248,17 @@ export function PanelChrome({ const onContentPointerDown = React.useCallback( (evt: React.PointerEvent) => { - // Ignore clicks inside buttons, links, canvas and svg elments + // When selected, ignore clicks inside buttons, links, canvas and svg elments // This does prevent a clicks inside a graphs from selecting panel as there is normal div above the canvas element that intercepts the click - if (evt.target instanceof Element && evt.target.closest('button,a,canvas,svg')) { + if (isSelected && evt.target instanceof Element && evt.target.closest('button,a,canvas,svg')) { + // Stop propagation otherwise row config editor will get selected + evt.stopPropagation(); return; } onSelect?.(evt); }, - [onSelect] + [isSelected, onSelect] ); const headerContent = ( @@ -384,6 +386,7 @@ export function PanelChrome({ menu={menu} title={typeof title === 'string' ? title : undefined} dragClass={dragClass} + onDragStart={onDragStart} offset={hoverHeaderOffset} onOpenMenu={onOpenMenu} > diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts b/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts index a9d5334925a..3e34eed16f7 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts +++ b/packages/grafana-ui/src/components/PanelChrome/PanelContext.ts @@ -55,6 +55,15 @@ export interface PanelContext { */ onAddAdHocFilter?: (item: AdHocFilterItem) => void; + /** + * Returns filters based on existing grouping or an empty array + */ + getFiltersBasedOnGrouping?: (items: AdHocFilterItem[]) => AdHocFilterItem[]; + /** + * + * Used to apply multiple filters at once + */ + onAddAdHocFilters?: (items: AdHocFilterItem[]) => void; /** * Enables modifying thresholds directly from the panel * diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx index f54f3cd6f22..f60fafe36f3 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialArcPath.tsx @@ -1,52 +1,137 @@ -import { GaugeDimensions, toRad } from './utils'; +import { useId, memo, HTMLAttributes, SVGProps } from 'react'; -export interface RadialArcPathProps { - startAngle: number; - dimensions: GaugeDimensions; - color: string; - glowFilter?: string; +import { FieldDisplay } from '@grafana/data'; + +import { RadialArcPathEndpointMarks } from './RadialArcPathEndpointMarks'; +import { getBarEndcapColors, getGradientCss } from './colors'; +import { RadialShape, RadialGaugeDimensions, GradientStop } from './types'; +import { drawRadialArcPath, toRad } from './utils'; + +export interface RadialArcPathPropsBase { arcLengthDeg: number; + barEndcaps?: boolean; + dimensions: RadialGaugeDimensions; + fieldDisplay: FieldDisplay; roundedBars?: boolean; + shape: RadialShape; + endpointMarker?: 'point' | 'glow'; + startAngle: number; + glowFilter?: string; + endpointMarkerGlowFilter?: string; } -export function RadialArcPath({ - startAngle: angle, - dimensions, - color, - glowFilter, - arcLengthDeg, - roundedBars, -}: RadialArcPathProps) { - const { radius, centerX, centerY, barWidth } = dimensions; +interface RadialArcPathPropsWithColor extends RadialArcPathPropsBase { + color: string; +} - if (arcLengthDeg === 360) { - // For some reason a 100% full arc cannot be rendered - arcLengthDeg = 359.99; +interface RadialArcPathPropsWithGradient extends RadialArcPathPropsBase { + gradient: GradientStop[]; +} + +type RadialArcPathProps = RadialArcPathPropsWithColor | RadialArcPathPropsWithGradient; + +export const RadialArcPath = memo( + ({ + arcLengthDeg, + dimensions, + fieldDisplay, + roundedBars, + shape, + endpointMarker, + barEndcaps, + startAngle: angle, + glowFilter, + endpointMarkerGlowFilter, + ...rest + }: RadialArcPathProps) => { + const id = useId(); + + const isGradient = 'gradient' in rest; + + const { vizWidth, vizHeight, radius, centerX, centerY, barWidth } = dimensions; + const pad = Math.ceil(Math.max(2, barWidth / 2)); // pad to cover stroke caps and glow in Safari + const boxX = Math.round(centerX - radius - barWidth - pad); + const boxY = Math.round(centerY - radius - barWidth - pad); + const boxSize = Math.round((radius + barWidth) * 2 + pad * 2); + + const path = drawRadialArcPath(angle, arcLengthDeg, dimensions, roundedBars); + + const startRadians = toRad(angle); + const endRadians = toRad(angle + arcLengthDeg); + + const xStart = centerX + radius * Math.cos(startRadians); + const yStart = centerY + radius * Math.sin(startRadians); + const xEnd = centerX + radius * Math.cos(endRadians); + const yEnd = centerY + radius * Math.sin(endRadians); + + const bgDivStyle: HTMLAttributes['style'] = { width: boxSize, height: vizHeight, marginLeft: boxX }; + const pathProps: SVGProps = {}; + if (isGradient) { + bgDivStyle.backgroundImage = getGradientCss(rest.gradient, shape); + pathProps.fill = 'none'; + pathProps.stroke = 'white'; + } else { + bgDivStyle.backgroundColor = rest.color; + pathProps.fill = 'none'; + pathProps.stroke = rest.color; + } + + let barEndcapColors: [string, string] | undefined; + if (barEndcaps) { + barEndcapColors = isGradient + ? getBarEndcapColors(rest.gradient, fieldDisplay.display.percent) + : [rest.color, rest.color]; + } + + const pathEl = ( + + ); + + return ( + <> + {isGradient && ( + + + + {pathEl} + + + )} + + + {isGradient ? ( + +
+ + ) : ( + pathEl + )} + {barEndcapColors?.[0] && } + {barEndcapColors?.[1] && ( + + )} + + + {endpointMarker && ( + + )} + + ); } +); - const startRadians = toRad(angle); - const endRadians = toRad(angle + arcLengthDeg); - - let x1 = centerX + radius * Math.cos(startRadians); - let y1 = centerY + radius * Math.sin(startRadians); - let x2 = centerX + radius * Math.cos(endRadians); - let y2 = centerY + radius * Math.sin(endRadians); - - const largeArc = arcLengthDeg > 180 ? 1 : 0; - - const path = ['M', x1, y1, 'A', radius, radius, 0, largeArc, 1, x2, y2].join(' '); - - return ( - - ); -} +RadialArcPath.displayName = 'RadialArcPath'; diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialArcPathEndpointMarks.test.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialArcPathEndpointMarks.test.tsx new file mode 100644 index 00000000000..af601e65c21 --- /dev/null +++ b/packages/grafana-ui/src/components/RadialGauge/RadialArcPathEndpointMarks.test.tsx @@ -0,0 +1,143 @@ +import { render, RenderResult } from '@testing-library/react'; + +import { FieldDisplay } from '@grafana/data'; + +import { RadialArcPathEndpointMarks, RadialArcPathEndpointMarksProps } from './RadialArcPathEndpointMarks'; +import { RadialGaugeDimensions } from './types'; + +const ser = new XMLSerializer(); + +const expectHTML = (result: RenderResult, expected: string) => { + let actual = ser.serializeToString(result.asFragment()).replace(/xmlns=".*?" /g, ''); + expect(actual).toEqual(expected.replace(/^\s*|\n/gm, '')); +}; + +describe('RadialArcPathEndpointMarks', () => { + const defaultDimensions = Object.freeze({ + centerX: 100, + centerY: 100, + radius: 80, + barWidth: 20, + vizWidth: 200, + vizHeight: 200, + margin: 10, + barIndex: 0, + thresholdsBarRadius: 0, + thresholdsBarWidth: 0, + thresholdsBarSpacing: 0, + scaleLabelsFontSize: 0, + scaleLabelsSpacing: 0, + scaleLabelsRadius: 0, + gaugeBottomY: 0, + }) satisfies RadialGaugeDimensions; + + const defaultFieldDisplay = Object.freeze({ + name: 'Test', + field: {}, + display: { text: '50', numeric: 50, color: '#FF0000' }, + hasLinks: false, + }) satisfies FieldDisplay; + + const defaultProps = Object.freeze({ + arcLengthDeg: 90, + dimensions: defaultDimensions, + fieldDisplay: defaultFieldDisplay, + startAngle: 0, + xStart: 100, + xEnd: 150, + yStart: 100, + yEnd: 50, + }) satisfies Omit; + + it('renders the expected marks when endpointMarker is "point" w/ a static color', () => { + expectHTML( + render( + + + + ), + '' + ); + }); + + it('renders the expected marks when endpointMarker is "point" w/ a gradient color', () => { + expectHTML( + render( + + + + ), + '' + ); + }); + + it('renders the expected marks when endpointMarker is "glow" w/ a static color', () => { + expectHTML( + render( + + + + ), + '' + ); + }); + + it('renders the expected marks when endpointMarker is "glow" w/ a gradient color', () => { + expectHTML( + render( + + + + ), + '' + ); + }); + + it('does not render the start mark when arcLengthDeg is less than the minimum angle for "point" endpointMarker', () => { + expectHTML( + render( + + + + ), + '' + ); + }); + + it('does not render anything when arcLengthDeg is less than the minimum angle for "glow" endpointMarker', () => { + expectHTML( + render( + + + + ), + '' + ); + }); + + it('does not render anything if endpointMarker is some other value', () => { + expectHTML( + render( + + {/* @ts-ignore: confirming the component doesn't throw */} + + + ), + '' + ); + }); +}); diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialArcPathEndpointMarks.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialArcPathEndpointMarks.tsx new file mode 100644 index 00000000000..7bd9a8c435f --- /dev/null +++ b/packages/grafana-ui/src/components/RadialGauge/RadialArcPathEndpointMarks.tsx @@ -0,0 +1,98 @@ +import { FieldDisplay } from '@grafana/data'; + +import { getEndpointMarkerColors, getGuideDotColor } from './colors'; +import { GradientStop, RadialGaugeDimensions } from './types'; +import { toRad } from './utils'; + +interface RadialArcPathEndpointMarksPropsBase { + arcLengthDeg: number; + dimensions: RadialGaugeDimensions; + fieldDisplay: FieldDisplay; + endpointMarker: 'point' | 'glow'; + roundedBars?: boolean; + startAngle: number; + glowFilter?: string; + endpointMarkerGlowFilter?: string; + xStart: number; + xEnd: number; + yStart: number; + yEnd: number; +} + +interface RadialArcPathEndpointMarksPropsWithColor extends RadialArcPathEndpointMarksPropsBase { + color: string; +} + +interface RadialArcPathEndpointMarksPropsWithGradient extends RadialArcPathEndpointMarksPropsBase { + gradient: GradientStop[]; +} + +export type RadialArcPathEndpointMarksProps = + | RadialArcPathEndpointMarksPropsWithColor + | RadialArcPathEndpointMarksPropsWithGradient; + +const ENDPOINT_MARKER_MIN_ANGLE = 10; +const DOT_OPACITY = 0.5; +const DOT_RADIUS_FACTOR = 0.4; +const MAX_DOT_RADIUS = 8; + +export function RadialArcPathEndpointMarks({ + startAngle: angle, + arcLengthDeg, + dimensions, + endpointMarker, + fieldDisplay, + xStart, + xEnd, + yStart, + yEnd, + roundedBars, + endpointMarkerGlowFilter, + glowFilter, + ...rest +}: RadialArcPathEndpointMarksProps) { + const isGradient = 'gradient' in rest; + const { radius, centerX, centerY, barWidth } = dimensions; + const endRadians = toRad(angle + arcLengthDeg); + + switch (endpointMarker) { + case 'point': { + const [pointColorStart, pointColorEnd] = isGradient + ? getEndpointMarkerColors(rest.gradient, fieldDisplay.display.percent) + : [getGuideDotColor(rest.color), getGuideDotColor(rest.color)]; + + const dotRadius = + endpointMarker === 'point' ? Math.min((barWidth / 2) * DOT_RADIUS_FACTOR, MAX_DOT_RADIUS) : barWidth / 2; + + return ( + <> + {arcLengthDeg > ENDPOINT_MARKER_MIN_ANGLE && ( + + )} + + + ); + } + case 'glow': + const offsetAngle = toRad(ENDPOINT_MARKER_MIN_ANGLE); + const xStartMark = centerX + radius * Math.cos(endRadians + offsetAngle); + const yStartMark = centerY + radius * Math.sin(endRadians + offsetAngle); + if (arcLengthDeg <= ENDPOINT_MARKER_MIN_ANGLE) { + break; + } + return ( + + ); + default: + break; + } + + return null; +} diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx index 2bacc3af3e8..719ec52c625 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialBar.tsx @@ -1,97 +1,64 @@ -import { GrafanaTheme2 } from '@grafana/data'; +import { FALLBACK_COLOR, FieldDisplay } from '@grafana/data'; import { useTheme2 } from '../../themes/ThemeContext'; import { RadialArcPath } from './RadialArcPath'; -import { RadialColorDefs } from './RadialColorDefs'; -import { GaugeDimensions, toRad } from './utils'; +import { RadialShape, RadialGaugeDimensions, GradientStop } from './types'; export interface RadialBarProps { - dimensions: GaugeDimensions; - colorDefs: RadialColorDefs; - angleRange: number; angle: number; - startAngle: number; + angleRange: number; + dimensions: RadialGaugeDimensions; + fieldDisplay: FieldDisplay; + gradient?: GradientStop[]; roundedBars?: boolean; - spotlightStroke: string; + endpointMarker?: 'point' | 'glow'; + shape: RadialShape; + startAngle: number; glowFilter?: string; + endpointMarkerGlowFilter?: string; } export function RadialBar({ - dimensions, - colorDefs, - angleRange, angle, - startAngle, + angleRange, + dimensions, + fieldDisplay, + gradient, roundedBars, - spotlightStroke, + endpointMarker, + shape, + startAngle, glowFilter, + endpointMarkerGlowFilter, }: RadialBarProps) { const theme = useTheme2(); - + const colorProps = gradient ? { gradient } : { color: fieldDisplay.display.color ?? FALLBACK_COLOR }; return ( <> - - {/** Track */} - - {/** The colored bar */} - - {spotlightStroke && angle > 8 && ( - - )} - - {colorDefs.getDefs()} + {/** Track */} + + {/** The colored bar */} + ); } - -interface SpotlightEffectProps { - dimensions: GaugeDimensions; - angle: number; - glowFilter?: string; - spotlightStroke: string; - theme: GrafanaTheme2; - roundedBars?: boolean; -} - -function SpotlightSquareEffect({ dimensions, angle, glowFilter, spotlightStroke, roundedBars }: SpotlightEffectProps) { - const { radius, centerX, centerY, barWidth } = dimensions; - - const angleRadian = toRad(angle); - const x1 = centerX + radius * Math.cos(angleRadian - 0.2); - const y1 = centerY + radius * Math.sin(angleRadian - 0.2); - const x2 = centerX + radius * Math.cos(angleRadian); - const y2 = centerY + radius * Math.sin(angleRadian); - - const path = ['M', x1, y1, 'A', radius, radius, 0, 0, 1, x2, y2].join(' '); - - return ( - - ); -} diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx index dbc93d2da7f..b51cb4ce2f1 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialBarSegmented.tsx @@ -1,126 +1,74 @@ -import { FieldDisplay } from '@grafana/data'; +import { memo } from 'react'; + +import { FALLBACK_COLOR, FieldDisplay } from '@grafana/data'; import { useTheme2 } from '../../themes/ThemeContext'; import { RadialArcPath } from './RadialArcPath'; -import { RadialColorDefs } from './RadialColorDefs'; -import { GaugeDimensions } from './utils'; +import { RadialShape, RadialGaugeDimensions, GradientStop } from './types'; +import { + getAngleBetweenSegments, + getFieldConfigMinMax, + getFieldDisplayProcessor, + getOptimalSegmentCount, +} from './utils'; export interface RadialBarSegmentedProps { fieldDisplay: FieldDisplay; - dimensions: GaugeDimensions; - colorDefs: RadialColorDefs; + dimensions: RadialGaugeDimensions; angleRange: number; startAngle: number; glowFilter?: string; segmentCount: number; segmentSpacing: number; + shape: RadialShape; + gradient?: GradientStop[]; } -export function RadialBarSegmented({ - fieldDisplay, - dimensions, - startAngle, - angleRange, - glowFilter, - segmentCount, - segmentSpacing, - colorDefs, -}: RadialBarSegmentedProps) { - const segments: React.ReactNode[] = []; - const theme = useTheme2(); - const segmentCountAdjusted = getOptimalSegmentCount(dimensions, segmentSpacing, segmentCount, angleRange); - const min = fieldDisplay.field.min ?? 0; - const max = fieldDisplay.field.max ?? 100; - const value = fieldDisplay.display.numeric; - const angleBetweenSegments = getAngleBetweenSegments(segmentSpacing, segmentCount, angleRange); - const segmentArcLengthDeg = angleRange / segmentCountAdjusted - angleBetweenSegments; +export const RadialBarSegmented = memo( + ({ + fieldDisplay, + dimensions, + startAngle, + angleRange, + glowFilter, + gradient, + segmentCount, + segmentSpacing, + shape, + }: RadialBarSegmentedProps) => { + const theme = useTheme2(); + const segments: React.ReactNode[] = []; + const segmentCountAdjusted = getOptimalSegmentCount(dimensions, segmentSpacing, segmentCount, angleRange); + const [min, max] = getFieldConfigMinMax(fieldDisplay); + const value = fieldDisplay.display.numeric; + const angleBetweenSegments = getAngleBetweenSegments(segmentSpacing, segmentCount, angleRange); + const segmentArcLengthDeg = angleRange / segmentCountAdjusted - angleBetweenSegments; + const displayProcessor = getFieldDisplayProcessor(fieldDisplay); - for (let i = 0; i < segmentCountAdjusted; i++) { - const angleValue = min + ((max - min) / segmentCountAdjusted) * i; - const angleColor = colorDefs.getSegmentColor(angleValue); - const segmentAngle = startAngle + (angleRange / segmentCountAdjusted) * i + 0.01; - const segmentColor = angleValue >= value ? theme.colors.action.hover : angleColor; + for (let i = 0; i < segmentCountAdjusted; i++) { + const angleValue = min + ((max - min) / segmentCountAdjusted) * i; + const segmentAngle = startAngle + (angleRange / segmentCountAdjusted) * i + 0.01; + const segmentColor = + angleValue >= value ? theme.colors.border.medium : (displayProcessor(angleValue).color ?? FALLBACK_COLOR); + const colorProps = angleValue < value && gradient ? { gradient } : { color: segmentColor }; - segments.push( - - ); + segments.push( + + ); + } + + return {segments}; } +); - return ( - <> - {segments} - {colorDefs.getDefs()} - - ); -} - -export function getAngleBetweenSegments(segmentSpacing: number, segmentCount: number, range: number) { - // Max spacing is 8 degrees between segments - // Changing this constant could be considered a breaking change - const maxAngleBetweenSegments = Math.max(range / 1.5 / segmentCount, 2); - return segmentSpacing * maxAngleBetweenSegments; -} - -function getOptimalSegmentCount( - dimensions: GaugeDimensions, - segmentSpacing: number, - segmentCount: number, - range: number -) { - const angleBetweenSegments = getAngleBetweenSegments(segmentSpacing, segmentCount, range); - - const innerRadius = dimensions.radius - dimensions.barWidth / 2; - const circumference = Math.PI * innerRadius * 2 * (range / 360); - const maxSegments = Math.floor(circumference / (angleBetweenSegments + 3)); - - return Math.min(maxSegments, segmentCount); -} - -// export function RadialSegmentLine({ -// gaugeId, -// center, -// angle, -// size, -// color, -// barWidth, -// roundedBars, -// glow, -// margin, -// segmentWidth, -// }: RadialSegmentProps) { -// const arcSize = size - barWidth; -// const radius = arcSize / 2 - margin; - -// const angleRad = (Math.PI * (angle - 90)) / 180; -// const lineLength = radius - barWidth; - -// const x1 = center + radius * Math.cos(angleRad); -// const y1 = center + radius * Math.sin(angleRad); -// const x2 = center + lineLength * Math.cos(angleRad); -// const y2 = center + lineLength * Math.sin(angleRad); - -// return ( -// -// ); -// } +RadialBarSegmented.displayName = 'RadialBarSegmented'; diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialColorDefs.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialColorDefs.tsx deleted file mode 100644 index 6bcf4876880..00000000000 --- a/packages/grafana-ui/src/components/RadialGauge/RadialColorDefs.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import tinycolor from 'tinycolor2'; - -import { DisplayProcessor, FALLBACK_COLOR, FieldDisplay, getFieldColorMode, GrafanaTheme2 } from '@grafana/data'; - -import { RadialGradientMode, RadialShape } from './RadialGauge'; -import { GaugeDimensions } from './utils'; - -export interface RadialColorDefsOptions { - gradient: RadialGradientMode; - fieldDisplay: FieldDisplay; - theme: GrafanaTheme2; - dimensions: GaugeDimensions; - shape: RadialShape; - gaugeId: string; - displayProcessor: DisplayProcessor; -} - -export class RadialColorDefs { - private colorToIds: Record = {}; - private defs: React.ReactNode[] = []; - - constructor(private options: RadialColorDefsOptions) {} - - getSegmentColor(forValue: number): string { - const { displayProcessor } = this.options; - const baseColor = displayProcessor(forValue).color ?? FALLBACK_COLOR; - - return this.getColor(baseColor, true); - } - - getColor(baseColor: string, forSegment?: boolean): string { - const { gradient, dimensions, gaugeId, fieldDisplay, shape, theme } = this.options; - - const id = `value-color-${baseColor}-${gaugeId}`; - - if (this.colorToIds[id]) { - return this.colorToIds[id]; - } - - // If no gradient, just return the base color - if (gradient === 'none') { - this.colorToIds[id] = baseColor; - return baseColor; - } - - const returnColor = (this.colorToIds[id] = `url(#${id})`); - const colorModeId = fieldDisplay.field.color?.mode; - const colorMode = getFieldColorMode(colorModeId); - const valuePercent = fieldDisplay.display.percent ?? 0; - - // Handle continusous color modes first - // If it's a segment color we don't want to do continuous gradients - if (colorMode.isContinuous && colorMode.getColors && !forSegment) { - const colors = colorMode.getColors(theme); - const count = colors.length; - - this.defs.push( - - {colors.map((stopColor, i) => ( - - ))} - - ); - - return returnColor; - } - - // For value based colors we want to stay more true to the specific color - // So a radial gradient that adds a bit of light and shade works best - if (colorMode.isByValue) { - const color1 = tinycolor(baseColor).darken(5); - - this.defs.push( - - - - - - ); - - return returnColor; - } - - // For fixed / palette based color scales we can create a more fun - // hue and light based linear gradient that we rotate/move with the value - - const x2 = shape === 'circle' ? 0 : dimensions.centerX + dimensions.radius; - const y2 = shape === 'circle' ? dimensions.centerY + dimensions.radius : 0; - const color1 = tinycolor(baseColor).spin(-20).darken(5); - const color2 = tinycolor(baseColor).saturate(20).spin(20).brighten(10); - - // this makes it so the gradient is always brightest at the current value - const transform = - shape === 'circle' - ? `rotate(${360 * valuePercent - 180} ${dimensions.centerX} ${dimensions.centerY})` - : `translate(-${dimensions.radius * 2 * (1 - valuePercent)}, 0)`; - - this.defs.push( - - {theme.isDark ? ( - <> - - - - ) : ( - <> - - - - )} - - ); - - return returnColor; - } - - getMainBarColor(): string { - return this.getColor(this.options.fieldDisplay.display.color ?? FALLBACK_COLOR); - } - - getDefs(): React.ReactNode[] { - return this.defs; - } -} diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.story.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.story.tsx index c098beda886..5c5faa64db7 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.story.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.story.tsx @@ -13,7 +13,8 @@ import { FieldColorModeId } from '@grafana/schema'; import { useTheme2 } from '../../themes/ThemeContext'; import { Stack } from '../Layout/Stack/Stack'; -import { RadialGauge, RadialGaugeProps, RadialGradientMode, RadialShape, RadialTextMode } from './RadialGauge'; +import { RadialGauge, RadialGaugeProps } from './RadialGauge'; +import { RadialShape, RadialTextMode } from './types'; interface StoryProps extends RadialGaugeProps { value: number; @@ -34,7 +35,6 @@ const meta: Meta = { }, args: { barWidthFactor: 0.2, - spotlight: false, glowBar: false, glowCenter: false, sparkline: false, @@ -42,7 +42,7 @@ const meta: Meta = { width: 200, height: 200, shape: 'circle', - gradient: 'none', + gradient: false, seriesCount: 1, segmentCount: 0, segmentSpacing: 0.2, @@ -56,14 +56,14 @@ const meta: Meta = { width: { control: { type: 'range', min: 50, max: 600 } }, height: { control: { type: 'range', min: 50, max: 600 } }, value: { control: { type: 'range', min: 0, max: 110 } }, - spotlight: { control: 'boolean' }, roundedBars: { control: 'boolean' }, sparkline: { control: 'boolean' }, thresholdsBar: { control: 'boolean' }, - gradient: { control: { type: 'radio' } }, + gradient: { control: { type: 'boolean' } }, seriesCount: { control: { type: 'range', min: 1, max: 20 } }, segmentCount: { control: { type: 'range', min: 0, max: 100 } }, segmentSpacing: { control: { type: 'range', min: 0, max: 1, step: 0.01 } }, + endpointMarker: { control: { type: 'select' }, options: ['none', 'point', 'glow'] }, colorScheme: { control: { type: 'select' }, options: [ @@ -102,57 +102,17 @@ export const Examples: StoryFn = (args) => {
Bar width
- - - - + + + +
Effects
- - - - + + + +
Shape: Gauge & color scale
@@ -160,14 +120,14 @@ export const Examples: StoryFn = (args) => { value={40} shape="gauge" width={250} - gradient="auto" + gradient colorScheme={FieldColorModeId.ContinuousGrYlRd} glowCenter={true} barWidthFactor={0.6} /> = (args) => { value={args.value ?? 70} color="blue" shape="gauge" - gradient="auto" + gradient sparkline={true} - spotlight glowBar={true} glowCenter={true} barWidthFactor={0.2} @@ -194,9 +153,8 @@ export const Examples: StoryFn = (args) => { value={args.value ?? 30} color="green" shape="gauge" - gradient="auto" + gradient sparkline={true} - spotlight glowBar={true} glowCenter={true} barWidthFactor={0.8} @@ -206,9 +164,8 @@ export const Examples: StoryFn = (args) => { color="red" shape="gauge" width={250} - gradient="auto" + gradient sparkline={true} - spotlight glowBar={true} glowCenter={true} barWidthFactor={0.2} @@ -218,9 +175,8 @@ export const Examples: StoryFn = (args) => { color="red" width={250} shape="gauge" - gradient="auto" + gradient sparkline={true} - spotlight glowBar={true} glowCenter={true} barWidthFactor={0.8} @@ -231,7 +187,7 @@ export const Examples: StoryFn = (args) => { = (args) => { = (args) => { = (args) => { = (args) => { value={args.value ?? 80} width={250} colorScheme={FieldColorModeId.ContinuousGrYlRd} - spotlight shape="gauge" - gradient="auto" + gradient glowBar={true} glowCenter={true} segmentCount={40} @@ -285,10 +239,9 @@ export const Examples: StoryFn = (args) => { @@ -296,7 +249,7 @@ export const Examples: StoryFn = (args) => { value={args.value ?? 70} width={250} colorScheme={FieldColorModeId.Thresholds} - gradient="auto" + gradient glowCenter={true} thresholdsBar={true} roundedBars={false} @@ -307,7 +260,7 @@ export const Examples: StoryFn = (args) => { value={args.value ?? 70} width={250} colorScheme={FieldColorModeId.Thresholds} - gradient="auto" + gradient glowCenter={true} thresholdsBar={true} roundedBars={false} @@ -347,14 +300,12 @@ export const Temp: StoryFn = (args) => { shape="gauge" roundedBars={false} barWidthFactor={0.8} - spotlight /> ); }; interface ExampleProps { - gradient?: RadialGradientMode; color?: string; seriesName?: string; value?: number; @@ -363,7 +314,7 @@ interface ExampleProps { max?: number; width?: number; height?: number; - spotlight?: boolean; + gradient?: boolean; glowBar?: boolean; glowCenter?: boolean; barWidthFactor?: number; @@ -376,12 +327,12 @@ interface ExampleProps { roundedBars?: boolean; thresholdsBar?: boolean; colorScheme?: FieldColorModeId; + endpointMarker?: RadialGaugeProps['endpointMarker']; decimals?: number; showScaleLabels?: boolean; } export function RadialGaugeExample({ - gradient = 'none', color, seriesName = 'Server A', value = 70, @@ -390,7 +341,7 @@ export function RadialGaugeExample({ max = 100, width = 200, height = 200, - spotlight = false, + gradient = false, glowBar = false, glowCenter = false, barWidthFactor = 0.4, @@ -403,6 +354,7 @@ export function RadialGaugeExample({ roundedBars = false, thresholdsBar = false, colorScheme = FieldColorModeId.Thresholds, + endpointMarker = 'glow', decimals = 0, showScaleLabels, }: ExampleProps) { @@ -480,7 +432,6 @@ export function RadialGaugeExample({ barWidthFactor={barWidthFactor} gradient={gradient} shape={shape} - spotlight={spotlight} glowBar={glowBar} glowCenter={glowCenter} textMode={textMode} @@ -490,6 +441,7 @@ export function RadialGaugeExample({ roundedBars={roundedBars} thresholdsBar={thresholdsBar} showScaleLabels={showScaleLabels} + endpointMarker={endpointMarker} /> ); } diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.test.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.test.tsx index e2fed36ec3f..783e3b764da 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.test.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.test.tsx @@ -1,13 +1,28 @@ import { render, screen } from '@testing-library/react'; +import { ComponentProps } from 'react'; import { RadialGaugeExample } from './RadialGauge.story'; describe('RadialGauge', () => { - it('should render', () => { - render(); - - expect(screen.getByRole('img')).toBeInTheDocument(); - }); + it.each([ + { description: 'default', props: {} }, + { description: 'gauge shape', props: { shape: 'gauge' } }, + { description: 'with gradient', props: { gradient: true } }, + { description: 'with glow bar', props: { glowBar: true } }, + { description: 'with glow center', props: { glowCenter: true } }, + { description: 'with segments', props: { segmentCount: 5 } }, + { description: 'with rounded bars', props: { roundedBars: true } }, + { description: 'with endpoint marker glow', props: { roundedBars: true, endpointMarker: 'glow' } }, + { description: 'with endpoint marker point', props: { roundedBars: true, endpointMarker: 'point' } }, + { description: 'with thresholds bar', props: { thresholdsBar: true } }, + { description: 'with sparkline', props: { sparkline: true } }, + ] satisfies Array<{ description: string; props?: ComponentProps }>)( + 'should render $description without throwing', + ({ props }) => { + render(); + expect(screen.getByRole('img')).toBeInTheDocument(); + } + ); it('should render threshold labels', () => { render(); diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx index 96e8b0f50f3..e60a3dfde31 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialGauge.tsx @@ -1,8 +1,8 @@ import { css, cx } from '@emotion/css'; -import { isNumber } from 'lodash'; -import { useId } from 'react'; +import { useId, ReactNode } from 'react'; -import { DisplayValueAlignmentFactors, FieldDisplay, getDisplayProcessor, GrafanaTheme2 } from '@grafana/data'; +import { DisplayValueAlignmentFactors, FALLBACK_COLOR, FieldDisplay, GrafanaTheme2, TimeRange } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { t } from '@grafana/i18n'; import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; @@ -10,12 +10,13 @@ import { getFormattedThresholds } from '../Gauge/utils'; import { RadialBar } from './RadialBar'; import { RadialBarSegmented } from './RadialBarSegmented'; -import { RadialColorDefs } from './RadialColorDefs'; import { RadialScaleLabels } from './RadialScaleLabels'; import { RadialSparkline } from './RadialSparkline'; import { RadialText } from './RadialText'; import { ThresholdsBar } from './ThresholdsBar'; +import { buildGradientColors } from './colors'; import { GlowGradient, MiddleCircleGlow, SpotlightGradient } from './effects'; +import { RadialShape, RadialTextMode } from './types'; import { calculateDimensions, getValueAngleForValue } from './utils'; export interface RadialGaugeProps { @@ -26,7 +27,7 @@ export interface RadialGaugeProps { * Circle or gauge (partial circle) */ shape?: RadialShape; - gradient?: RadialGradientMode; + gradient?: boolean; /** * Bar width is always relative to size of the gauge. * But this gives you control over the width relative to size. @@ -34,12 +35,14 @@ export interface RadialGaugeProps { * Defaults to 0.4 **/ barWidthFactor?: number; - /** Adds a white spotlight for the end position */ - spotlight?: boolean; glowBar?: boolean; glowCenter?: boolean; roundedBars?: boolean; thresholdsBar?: boolean; + /** + * Specify if an endpoint marker should be shown at the end of the bar + */ + endpointMarker?: 'point' | 'glow'; /** * Number of segments depends on size of gauge but this * factor 1-10 gives you relative control @@ -66,12 +69,9 @@ export interface RadialGaugeProps { showScaleLabels?: boolean; /** For data links */ onClick?: React.MouseEventHandler; + timeRange?: TimeRange; } -export type RadialGradientMode = 'none' | 'auto'; -export type RadialTextMode = 'auto' | 'value_and_name' | 'value' | 'name' | 'none'; -export type RadialShape = 'circle' | 'gauge'; - /** * https://developers.grafana.com/ui/latest/index.html?path=/docs/plugins-radialgauge--docs */ @@ -80,9 +80,8 @@ export function RadialGauge(props: RadialGaugeProps) { width = 256, height = 256, shape = 'circle', - gradient = 'none', + gradient = false, barWidthFactor = 0.4, - spotlight = false, glowBar = false, glowCenter = false, textMode = 'auto', @@ -92,6 +91,7 @@ export function RadialGauge(props: RadialGaugeProps) { roundedBars = true, thresholdsBar = false, showScaleLabels = false, + endpointMarker, onClick, values, } = props; @@ -99,17 +99,23 @@ export function RadialGauge(props: RadialGaugeProps) { const gaugeId = useId(); const styles = useStyles2(getStyles); + let effectiveTextMode = textMode; + if (effectiveTextMode === 'auto') { + effectiveTextMode = vizCount === 1 ? 'value' : 'value_and_name'; + } + const startAngle = shape === 'gauge' ? 250 : 0; const endAngle = shape === 'gauge' ? 110 : 360; - const defs: React.ReactNode[] = []; - const graphics: React.ReactNode[] = []; - let sparklineElement: React.ReactNode | null = null; + const defs: ReactNode[] = []; + const graphics: ReactNode[] = []; + let sparklineElement: ReactNode | null = null; for (let barIndex = 0; barIndex < values.length; barIndex++) { const displayValue = values[barIndex]; const { angle, angleRange } = getValueAngleForValue(displayValue, startAngle, endAngle); - const color = displayValue.display.color ?? 'gray'; + const gradientStops = gradient ? buildGradientColors(theme, displayValue) : undefined; + const color = displayValue.display.color ?? FALLBACK_COLOR; const dimensions = calculateDimensions( width, height, @@ -122,20 +128,14 @@ export function RadialGauge(props: RadialGaugeProps) { showScaleLabels ); - const displayProcessor = getFieldDisplayProcessor(displayValue); + // FIXME: I want to move the ids for these filters into a context which the children + // can reference via a hook, rather than passing them down as props const spotlightGradientId = `spotlight-${barIndex}-${gaugeId}`; + const spotlightGradientRef = endpointMarker === 'glow' ? `url(#${spotlightGradientId})` : undefined; const glowFilterId = `glow-${gaugeId}`; - const colorDefs = new RadialColorDefs({ - gradient, - fieldDisplay: displayValue, - theme, - dimensions, - shape, - gaugeId, - displayProcessor, - }); + const glowFilterRef = glowBar ? `url(#${glowFilterId})` : undefined; - if (spotlight && theme.isDark) { + if (endpointMarker === 'glow') { defs.push( ); } else { @@ -167,13 +168,16 @@ export function RadialGauge(props: RadialGaugeProps) { ); } @@ -181,7 +185,7 @@ export function RadialGauge(props: RadialGaugeProps) { // These elements are only added for first value / bar if (barIndex === 0) { if (glowBar) { - defs.push(); + defs.push(); } if (glowCenter) { @@ -191,14 +195,14 @@ export function RadialGauge(props: RadialGaugeProps) { graphics.push( ); @@ -232,8 +236,9 @@ export function RadialGauge(props: RadialGaugeProps) { endAngle={endAngle} angleRange={angleRange} roundedBars={roundedBars} - glowFilter={`url(#${glowFilterId})`} - colorDefs={colorDefs} + glowFilter={glowFilterRef} + shape={shape} + gradient={gradientStops} /> ); } @@ -247,6 +252,7 @@ export function RadialGauge(props: RadialGaugeProps) { theme={theme} color={color} shape={shape} + textMode={effectiveTextMode} /> ); } @@ -256,7 +262,7 @@ export function RadialGauge(props: RadialGaugeProps) { const body = ( <> - {defs} + {defs.length > 0 && {defs}} {graphics} {sparklineElement} @@ -272,23 +278,16 @@ export function RadialGauge(props: RadialGaugeProps) { } return ( -
+
{body}
); } -function getFieldDisplayProcessor(displayValue: FieldDisplay) { - if (displayValue.view && isNumber(displayValue.colIndex)) { - const dp = displayValue.view.getFieldDisplayProcessor(displayValue.colIndex); - if (dp) { - return dp; - } - } - - return getDisplayProcessor(); -} - function getStyles(theme: GrafanaTheme2) { return { vizWrapper: css({ diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialScaleLabels.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialScaleLabels.tsx index 994b3b35eac..6588150602a 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialScaleLabels.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialScaleLabels.tsx @@ -1,87 +1,84 @@ +import { memo } from 'react'; + import { FieldDisplay, GrafanaTheme2, Threshold } from '@grafana/data'; import { t } from '@grafana/i18n'; import { measureText } from '../../utils/measureText'; -import { GaugeDimensions, toCartesian } from './utils'; +import { RadialGaugeDimensions } from './types'; +import { getFieldConfigMinMax, toCartesian } from './utils'; interface RadialScaleLabelsProps { fieldDisplay: FieldDisplay; theme: GrafanaTheme2; thresholds: Threshold[]; - dimensions: GaugeDimensions; + dimensions: RadialGaugeDimensions; startAngle: number; endAngle: number; angleRange: number; } -export function RadialScaleLabels({ - fieldDisplay, - thresholds, - theme, - dimensions, - startAngle, - endAngle, - angleRange, -}: RadialScaleLabelsProps) { - const { centerX, centerY, scaleLabelsFontSize, scaleLabelsRadius } = dimensions; +const LINE_HEIGHT_FACTOR = 1.2; - const fieldConfig = fieldDisplay.field; - const min = fieldConfig.min ?? 0; - const max = fieldConfig.max ?? 100; +export const RadialScaleLabels = memo( + ({ fieldDisplay, thresholds, theme, dimensions, startAngle, endAngle, angleRange }: RadialScaleLabelsProps) => { + const { centerX, centerY, scaleLabelsFontSize, scaleLabelsRadius } = dimensions; + const [min, max] = getFieldConfigMinMax(fieldDisplay); - const fontSize = scaleLabelsFontSize; - const textLineHeight = scaleLabelsFontSize * 1.2; - const radius = scaleLabelsRadius - textLineHeight; + const fontSize = scaleLabelsFontSize; + const textLineHeight = scaleLabelsFontSize * LINE_HEIGHT_FACTOR; + const radius = scaleLabelsRadius - textLineHeight; - function getTextPosition(text: string, value: number, index: number) { - const isLast = index === thresholds.length - 1; - const isFirst = index === 0; + function getTextPosition(text: string, value: number, index: number) { + const isLast = index === thresholds.length - 1; + const isFirst = index === 0; - let valueDeg = ((value - min) / (max - min)) * angleRange; - let finalAngle = startAngle + valueDeg; + let valueDeg = ((value - min) / (max - min)) * angleRange; + let finalAngle = startAngle + valueDeg; - // Now adjust the final angle based on the label text width and the labels position on the arc - let measure = measureText(text, fontSize, theme.typography.fontWeightMedium); - let textWidthAngle = (measure.width / (2 * Math.PI * radius)) * angleRange; + // Now adjust the final angle based on the label text width and the labels position on the arc + let measure = measureText(text, fontSize, theme.typography.fontWeightMedium); + let textWidthAngle = (measure.width / (2 * Math.PI * radius)) * angleRange; - // the centering is different for gauge or circle shapes for some reason - finalAngle -= endAngle < 180 ? textWidthAngle : textWidthAngle / 2; + // the centering is different for gauge or circle shapes for some reason + finalAngle -= endAngle < 180 ? textWidthAngle : textWidthAngle / 2; - // For circle gauges we need to shift the first label more - if (isFirst) { - finalAngle += textWidthAngle; + // For circle gauges we need to shift the first label more + if (isFirst) { + finalAngle += textWidthAngle; + } + + // For circle gauges we need to shift the last label more + if (isLast && endAngle === 360) { + finalAngle -= textWidthAngle; + } + + const position = toCartesian(centerX, centerY, radius, finalAngle); + + return { ...position, transform: `rotate(${finalAngle}, ${position.x}, ${position.y})` }; } - // For circle gauges we need to shift the last label more - if (isLast && endAngle === 360) { - finalAngle -= textWidthAngle; - } - - const position = toCartesian(centerX, centerY, radius, finalAngle); - - return { ...position, transform: `rotate(${finalAngle}, ${position.x}, ${position.y})` }; + return ( + + {thresholds.map((threshold, index) => { + const labelPos = getTextPosition(String(threshold.value), threshold.value, index); + return ( + + {threshold.value} + + ); + })} + + ); } +); - return ( - - {thresholds.map((threshold, index) => { - const labelPos = getTextPosition(String(threshold.value), threshold.value, index); - - return ( - - {threshold.value} - - ); - })} - - ); -} +RadialScaleLabels.displayName = 'RadialScaleLabels'; diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialSparkline.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialSparkline.tsx index 7a25fe3201a..4a52d5241d5 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialSparkline.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialSparkline.tsx @@ -1,52 +1,76 @@ -import { css } from '@emotion/css'; +import { memo, useMemo } from 'react'; import { FieldDisplay, GrafanaTheme2, FieldConfig } from '@grafana/data'; import { GraphFieldConfig, GraphGradientMode, LineInterpolation } from '@grafana/schema'; import { Sparkline } from '../Sparkline/Sparkline'; -import { RadialShape } from './RadialGauge'; -import { GaugeDimensions } from './utils'; +import { RadialShape, RadialTextMode, RadialGaugeDimensions } from './types'; interface RadialSparklineProps { - sparkline: FieldDisplay['sparkline']; - dimensions: GaugeDimensions; - theme: GrafanaTheme2; color?: string; - shape?: RadialShape; + dimensions: RadialGaugeDimensions; + shape: RadialShape; + sparkline: FieldDisplay['sparkline']; + textMode: Exclude; + theme: GrafanaTheme2; } -export function RadialSparkline({ sparkline, dimensions, theme, color, shape }: RadialSparklineProps) { - if (!sparkline) { - return null; + +const SPARKLINE_HEIGHT_DIVISOR = 4; +const SPARKLINE_HEIGHT_DIVISOR_NAME_AND_VALUE = 4; +const SPARKLINE_WIDTH_FACTOR_ARC = 1.4; +const SPARKLINE_WIDTH_FACTOR_CIRCLE = 1.6; +const SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE = 4; +const SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE_NAME_AND_VALUE = 3.3; +const SPARKLINE_SPACING = 8; + +export function getSparklineDimensions( + radius: number, + barWidth: number, + showNameAndValue: boolean, + shape: RadialShape +): { width: number; height: number } { + const height = radius / (showNameAndValue ? SPARKLINE_HEIGHT_DIVISOR_NAME_AND_VALUE : SPARKLINE_HEIGHT_DIVISOR); + const width = radius * (shape === 'gauge' ? SPARKLINE_WIDTH_FACTOR_ARC : SPARKLINE_WIDTH_FACTOR_CIRCLE) - barWidth; + return { width, height }; +} + +export const RadialSparkline = memo( + ({ sparkline, dimensions, theme, color, shape, textMode }: RadialSparklineProps) => { + const { radius, barWidth } = dimensions; + + const showNameAndValue = textMode === 'value_and_name'; + const { width, height } = getSparklineDimensions(radius, barWidth, showNameAndValue, shape); + const topPos = + shape === 'gauge' + ? dimensions.gaugeBottomY - height - SPARKLINE_SPACING + : `calc(50% + ${radius / (showNameAndValue ? SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE_NAME_AND_VALUE : SPARKLINE_TOP_OFFSET_DIVISOR_CIRCLE)}px)`; + + const config: FieldConfig = useMemo( + () => ({ + color: { + mode: 'fixed', + fixedColor: color ?? 'blue', + }, + custom: { + gradientMode: GraphGradientMode.Opacity, + fillOpacity: 40, + lineInterpolation: LineInterpolation.Smooth, + }, + }), + [color] + ); + + if (!sparkline) { + return null; + } + + return ( +
+ +
+ ); } +); - const { radius, barWidth } = dimensions; - - const height = radius / 4; - const widthFactor = shape === 'gauge' ? 1.6 : 1.4; - const width = radius * widthFactor - barWidth; - const topPos = shape === 'gauge' ? `${dimensions.gaugeBottomY - height}px` : `calc(50% + ${radius / 2.8}px)`; - - const styles = css({ - position: 'absolute', - top: topPos, - }); - - const config: FieldConfig = { - color: { - mode: 'fixed', - fixedColor: color ?? 'blue', - }, - custom: { - gradientMode: GraphGradientMode.Opacity, - fillOpacity: 40, - lineInterpolation: LineInterpolation.Smooth, - }, - }; - - return ( -
- -
- ); -} +RadialSparkline.displayName = 'RadialSparkline'; diff --git a/packages/grafana-ui/src/components/RadialGauge/RadialText.tsx b/packages/grafana-ui/src/components/RadialGauge/RadialText.tsx index d01a2d99570..dc094b7261c 100644 --- a/packages/grafana-ui/src/components/RadialGauge/RadialText.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/RadialText.tsx @@ -1,152 +1,150 @@ -import { css } from '@emotion/css'; +import { memo } from 'react'; -import { DisplayValue, DisplayValueAlignmentFactors, formattedValueToString, GrafanaTheme2 } from '@grafana/data'; +import { + DisplayValue, + DisplayValueAlignmentFactors, + FieldSparkline, + formattedValueToString, + GrafanaTheme2, +} from '@grafana/data'; -import { useStyles2 } from '../../themes/ThemeContext'; import { calculateFontSize } from '../../utils/measureText'; -import { RadialShape, RadialTextMode } from './RadialGauge'; -import { GaugeDimensions } from './utils'; - -// function toCartesian(centerX: number, centerY: number, radius: number, angleInDegrees: number) { -// let radian = ((angleInDegrees - 90) * Math.PI) / 180.0; -// return { -// x: centerX + radius * Math.cos(radian), -// y: centerY + radius * Math.sin(radian), -// }; -// } +import { RadialShape, RadialTextMode, RadialGaugeDimensions } from './types'; interface RadialTextProps { displayValue: DisplayValue; theme: GrafanaTheme2; - dimensions: GaugeDimensions; - textMode: RadialTextMode; - vizCount: number; + dimensions: RadialGaugeDimensions; + textMode: Exclude; shape: RadialShape; + sparkline?: FieldSparkline; alignmentFactors?: DisplayValueAlignmentFactors; valueManualFontSize?: number; nameManualFontSize?: number; } -export function RadialText({ - displayValue, - theme, - dimensions, - textMode, - vizCount, - shape, - alignmentFactors, - valueManualFontSize, - nameManualFontSize, -}: RadialTextProps) { - const styles = useStyles2(getStyles); - const { centerX, centerY, radius, barWidth } = dimensions; +const LINE_HEIGHT_FACTOR = 1.21; +const VALUE_WIDTH_TO_RADIUS_FACTOR = 0.82; +const NAME_TO_HEIGHT_FACTOR = 0.45; +const LARGE_RADIUS_SCALING_DECAY = 0.86; +const MAX_TEXT_WIDTH_DIVISOR = 7; +const MAX_NAME_HEIGHT_DIVISOR = 4; +const VALUE_SPACE_PERCENTAGE = 0.7; +const SPARKLINE_SPACING = 8; +const MIN_VALUE_FONT_SIZE = 1; +const MIN_NAME_FONT_SIZE = 10; +const MIN_UNIT_FONT_SIZE = 6; - if (textMode === 'none') { - return null; - } +export const RadialText = memo( + ({ + displayValue, + theme, + dimensions, + textMode, + shape, + sparkline, + alignmentFactors, + valueManualFontSize, + nameManualFontSize, + }: RadialTextProps) => { + const { centerX, centerY, radius, barWidth } = dimensions; - if (textMode === 'auto') { - textMode = vizCount === 1 ? 'value' : 'value_and_name'; - } + if (textMode === 'none') { + return null; + } - const nameToAlignTo = (alignmentFactors ? alignmentFactors.title : displayValue.title) ?? ''; - const valueToAlignTo = formattedValueToString(alignmentFactors ? alignmentFactors : displayValue); + const nameToAlignTo = (alignmentFactors ? alignmentFactors.title : displayValue.title) ?? ''; + const valueToAlignTo = formattedValueToString(alignmentFactors ? alignmentFactors : displayValue); - const showValue = textMode === 'value' || textMode === 'value_and_name'; - const showName = textMode === 'name' || textMode === 'value_and_name'; - const maxTextWidth = radius * 2 - barWidth - radius / 7; + const showValue = textMode === 'value' || textMode === 'value_and_name'; + const showName = textMode === 'name' || textMode === 'value_and_name'; + const maxTextWidth = radius * 2 - barWidth - radius / MAX_TEXT_WIDTH_DIVISOR; - // Not sure where this comes from but svg text is not using body line-height - const lineHeight = 1.21; - const valueWidthToRadiusFactor = 0.85; - const nameToHeightFactor = 0.45; - const largeRadiusScalingDecay = 0.86; + // This pow 0.92 factor is to create a decay so the font size does not become rediculously large for very large panels + let maxValueHeight = VALUE_WIDTH_TO_RADIUS_FACTOR * Math.pow(radius, LARGE_RADIUS_SCALING_DECAY); + let maxNameHeight = radius / MAX_NAME_HEIGHT_DIVISOR; - // This pow 0.92 factor is to create a decay so the font size does not become rediculously large for very large panels - let maxValueHeight = valueWidthToRadiusFactor * Math.pow(radius, largeRadiusScalingDecay); - let maxNameHeight = radius / 4; + if (showValue && showName) { + maxValueHeight = VALUE_WIDTH_TO_RADIUS_FACTOR * Math.pow(radius, LARGE_RADIUS_SCALING_DECAY); + maxNameHeight = NAME_TO_HEIGHT_FACTOR * Math.pow(radius, LARGE_RADIUS_SCALING_DECAY); + } - if (showValue && showName) { - maxValueHeight = valueWidthToRadiusFactor * Math.pow(radius, largeRadiusScalingDecay); - maxNameHeight = nameToHeightFactor * Math.pow(radius, largeRadiusScalingDecay); - } - - const valueFontSize = - valueManualFontSize ?? - calculateFontSize( - valueToAlignTo, - maxTextWidth, - maxValueHeight, - lineHeight, - undefined, - theme.typography.body.fontWeight + const valueFontSize = Math.max( + valueManualFontSize ?? + calculateFontSize( + valueToAlignTo, + maxTextWidth, + maxValueHeight, + LINE_HEIGHT_FACTOR, + undefined, + theme.typography.body.fontWeight + ), + MIN_VALUE_FONT_SIZE ); - const nameFontSize = - nameManualFontSize ?? - calculateFontSize( - nameToAlignTo, - maxTextWidth, - maxNameHeight, - lineHeight, - undefined, - theme.typography.body.fontWeight + const nameFontSize = Math.max( + nameManualFontSize ?? + calculateFontSize( + nameToAlignTo, + maxTextWidth, + maxNameHeight, + LINE_HEIGHT_FACTOR, + undefined, + theme.typography.body.fontWeight + ), + MIN_NAME_FONT_SIZE ); - const unitFontSize = Math.max(valueFontSize * 0.7, 5); - const valueHeight = valueFontSize * lineHeight; - const nameHeight = nameFontSize * lineHeight; + const unitFontSize = Math.max(valueFontSize * VALUE_SPACE_PERCENTAGE, MIN_UNIT_FONT_SIZE); + const valueHeight = valueFontSize * LINE_HEIGHT_FACTOR; + const nameHeight = nameFontSize * LINE_HEIGHT_FACTOR; - const valueY = showName ? centerY - nameHeight / 2 : centerY; - const valueNameSpacing = valueHeight / 3.5; - const nameY = showValue ? valueY + valueHeight / 2 + valueNameSpacing : centerY; - const nameColor = showValue ? theme.colors.text.secondary : theme.colors.text.primary; - const suffixShift = (valueFontSize - unitFontSize * 1.2) / 2; + const valueY = showName ? centerY - nameHeight * (1 - VALUE_SPACE_PERCENTAGE) : centerY; + const nameY = showValue ? valueY + valueHeight * VALUE_SPACE_PERCENTAGE : centerY; + const nameColor = showValue ? theme.colors.text.secondary : theme.colors.text.primary; - // For gauge shape we shift text up a bit - const valueDy = shape === 'gauge' ? -valueFontSize * 0.3 : 0; - const nameDy = shape === 'gauge' ? -nameFontSize * 0.7 : 0; + // adjust the text up on gauges and when sparklines are present + let yOffset = valueFontSize / 4; + if (shape === 'gauge') { + // we render from the center of the gauge, so move up by half of half of the total height + yOffset -= (valueHeight + nameHeight) / 4; + } + if (sparkline) { + yOffset -= SPARKLINE_SPACING; + } - return ( - - {showValue && ( - - {displayValue.prefix ?? ''} - {displayValue.text} - - {displayValue.suffix ?? ''} - - - )} - {showName && ( - - {displayValue.title} - - )} - - ); -} + return ( + + {showValue && ( + + {displayValue.prefix ?? ''} + {displayValue.text} + {displayValue.suffix ?? ''} + + )} + {showName && ( + + {displayValue.title} + + )} + + ); + } +); -const getStyles = (theme: GrafanaTheme2) => ({ - text: css({ - verticalAlign: 'bottom', - }), -}); +RadialText.displayName = 'RadialText'; diff --git a/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx b/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx index 602038ccf10..cb2829934b9 100644 --- a/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/ThresholdsBar.tsx @@ -1,20 +1,22 @@ import { FieldDisplay, Threshold } from '@grafana/data'; import { RadialArcPath } from './RadialArcPath'; -import { RadialColorDefs } from './RadialColorDefs'; -import { GaugeDimensions } from './utils'; +import { GradientStop, RadialGaugeDimensions, RadialShape } from './types'; +import { getFieldConfigMinMax } from './utils'; -export interface Props { - dimensions: GaugeDimensions; +interface ThresholdsBarProps { + dimensions: RadialGaugeDimensions; angleRange: number; startAngle: number; endAngle: number; + shape: RadialShape; fieldDisplay: FieldDisplay; roundedBars?: boolean; glowFilter?: string; - colorDefs: RadialColorDefs; thresholds: Threshold[]; + gradient?: GradientStop[]; } + export function ThresholdsBar({ dimensions, fieldDisplay, @@ -22,19 +24,18 @@ export function ThresholdsBar({ angleRange, roundedBars, glowFilter, - colorDefs, thresholds, -}: Props) { - const fieldConfig = fieldDisplay.field; - const min = fieldConfig.min ?? 0; - const max = fieldConfig.max ?? 100; - + shape, + gradient, +}: ThresholdsBarProps) { const thresholdDimensions = { ...dimensions, barWidth: dimensions.thresholdsBarWidth, radius: dimensions.thresholdsBarRadius, }; + const [min, max] = getFieldConfigMinMax(fieldDisplay); + let currentStart = startAngle; let paths: React.ReactNode[] = []; @@ -48,27 +49,26 @@ export function ThresholdsBar({ valueDeg = 0; } - let lengthDeg = valueDeg - currentStart + startAngle; + const lengthDeg = valueDeg - currentStart + startAngle; + const colorProps = gradient ? { gradient } : { color: threshold.color }; paths.push( ); currentStart += lengthDeg; } - return ( - <> - {paths} - {colorDefs.getDefs()} - - ); + return {paths}; } diff --git a/packages/grafana-ui/src/components/RadialGauge/__snapshots__/colors.test.ts.snap b/packages/grafana-ui/src/components/RadialGauge/__snapshots__/colors.test.ts.snap new file mode 100644 index 00000000000..97b053c2d61 --- /dev/null +++ b/packages/grafana-ui/src/components/RadialGauge/__snapshots__/colors.test.ts.snap @@ -0,0 +1,144 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RadialGauge color utils buildGradientColors should map threshold colors correctly (with baseColor if displayProcessor does not return colors) 1`] = ` +[ + { + "color": "#444444", + "percent": 0, + }, + { + "color": "#FADE2A", + "percent": 0.5, + }, + { + "color": "#F2495C", + "percent": 0.8, + }, + { + "color": "#444444", + "percent": 1, + }, +] +`; + +exports[`RadialGauge color utils buildGradientColors should map threshold colors correctly (with baseColor if displayProcessor does not return colors) 2`] = ` +[ + { + "color": "#FF0000", + "percent": 0, + }, + { + "color": "#FADE2A", + "percent": 0.5, + }, + { + "color": "#F2495C", + "percent": 0.8, + }, + { + "color": "#FF0000", + "percent": 1, + }, +] +`; + +exports[`RadialGauge color utils buildGradientColors should return gradient colors for by-value color mode in dark theme 1`] = ` +[ + { + "color": "#181b1f", + "percent": 0, + }, + { + "color": "#1F60C4", + "percent": 1, + }, +] +`; + +exports[`RadialGauge color utils buildGradientColors should return gradient colors for by-value color mode in light theme 1`] = ` +[ + { + "color": "#ffffff", + "percent": 0, + }, + { + "color": "#1250B0", + "percent": 1, + }, +] +`; + +exports[`RadialGauge color utils buildGradientColors should return gradient colors for continuous color modes 1`] = ` +[ + { + "color": "rgb(0, 32, 81)", + "percent": 0, + }, + { + "color": "rgb(17, 54, 108)", + "percent": 0.125, + }, + { + "color": "rgb(60, 77, 110)", + "percent": 0.25, + }, + { + "color": "rgb(98, 100, 111)", + "percent": 0.375, + }, + { + "color": "rgb(127, 124, 117)", + "percent": 0.5, + }, + { + "color": "rgb(154, 148, 120)", + "percent": 0.625, + }, + { + "color": "rgb(187, 175, 113)", + "percent": 0.75, + }, + { + "color": "rgb(226, 203, 92)", + "percent": 0.875, + }, + { + "color": "rgb(253, 234, 69)", + "percent": 1, + }, +] +`; + +exports[`RadialGauge color utils buildGradientColors should return gradient colors for fixed color mode in dark theme 1`] = ` +[ + { + "color": "#37237a", + "percent": 0, + }, + { + "color": "#a146da", + "percent": 0.75, + }, + { + "color": "#a146da", + "percent": 1, + }, +] +`; + +exports[`RadialGauge color utils buildGradientColors should return gradient colors for fixed color mode in light theme 1`] = ` +[ + { + "color": "#a146da", + "percent": 0, + }, + { + "color": "#3e2b9a", + "percent": 0.75, + }, + { + "color": "#3e2b9a", + "percent": 1, + }, +] +`; diff --git a/packages/grafana-ui/src/components/RadialGauge/__snapshots__/utils.test.ts.snap b/packages/grafana-ui/src/components/RadialGauge/__snapshots__/utils.test.ts.snap new file mode 100644 index 00000000000..9d12b97a6c3 --- /dev/null +++ b/packages/grafana-ui/src/components/RadialGauge/__snapshots__/utils.test.ts.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for center x and y 1`] = `"M 150 120 A 80 80 0 1 1 149.98603736605492 120.00000121846968"`; + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for half arc 1`] = `"M 100 20 A 80 80 0 0 1 100 180"`; + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for narrow bar width 1`] = `"M 100 20 A 80 80 0 0 1 100 180"`; + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for narrow radius 1`] = `"M 100 50 A 50 50 0 0 1 100 150"`; + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for quarter arc 1`] = `"M 100 20 A 80 80 0 0 1 180 100"`; + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for rounded bars 1`] = `"M 100 20 A 80 80 0 1 1 20 100.00000000000001"`; + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for three quarter arc 1`] = `"M 100 20 A 80 80 0 1 1 20 100.00000000000001"`; + +exports[`RadialGauge utils drawRadialArcPath should draw correct path for wide bar width 1`] = `"M 100 20 A 80 80 0 0 1 100 180"`; diff --git a/packages/grafana-ui/src/components/RadialGauge/colors.test.ts b/packages/grafana-ui/src/components/RadialGauge/colors.test.ts new file mode 100644 index 00000000000..36a4c70d619 --- /dev/null +++ b/packages/grafana-ui/src/components/RadialGauge/colors.test.ts @@ -0,0 +1,277 @@ +import { defaultsDeep } from 'lodash'; + +import { createTheme, Field, FieldDisplay, FieldType, ThresholdsMode } from '@grafana/data'; +import { FieldColorModeId } from '@grafana/schema'; + +import { + buildGradientColors, + colorAtGradientPercent, + getBarEndcapColors, + getEndpointMarkerColors, + getGradientCss, + getGradientStopsForPercent, +} from './colors'; + +export type DeepPartial = { + [P in keyof T]?: DeepPartial; +}; + +describe('RadialGauge color utils', () => { + describe('buildGradientColors', () => { + const createField = (colorMode: FieldColorModeId): Field => + ({ + type: FieldType.number, + name: 'Test Field', + config: { + color: { + mode: colorMode, + }, + thresholds: { + mode: ThresholdsMode.Absolute, + steps: [ + { value: -Infinity, color: 'green' }, + { value: 50, color: 'yellow' }, + { value: 80, color: 'red' }, + ], + }, + }, + values: [70, 40, 30, 90, 55], + }) satisfies Field; + + const buildFieldDisplay = (field: Field, part = {}): FieldDisplay => + defaultsDeep(part, { + field: field.config, + colIndex: 0, + view: { + getFieldDisplayProcessor: jest.fn(() => jest.fn(() => ({ color: undefined }))), + }, + display: { + numeric: 75, + }, + }); + + it('should map threshold colors correctly (with baseColor if displayProcessor does not return colors)', () => { + expect( + buildGradientColors( + createTheme(), + buildFieldDisplay(createField(FieldColorModeId.Thresholds), { + view: { getFieldDisplayProcessor: jest.fn(() => jest.fn(() => ({ color: '#444444' }))) }, + }) + ) + ).toMatchSnapshot(); + }); + + it('should map threshold colors correctly (with baseColor if displayProcessor does not return colors)', () => { + expect( + buildGradientColors(createTheme(), buildFieldDisplay(createField(FieldColorModeId.Thresholds)), '#FF0000') + ).toMatchSnapshot(); + }); + + it('should return gradient colors for continuous color modes', () => { + expect( + buildGradientColors( + createTheme(), + buildFieldDisplay(createField(FieldColorModeId.ContinuousCividis)), + '#00FF00' + ) + ).toMatchSnapshot(); + }); + + it.each(['dark', 'light'] as const)('should return gradient colors for by-value color mode in %s theme', (mode) => { + expect( + buildGradientColors( + createTheme({ colors: { mode } }), + buildFieldDisplay(createField(FieldColorModeId.ContinuousBlues)) + ) + ).toMatchSnapshot(); + }); + + it.each(['dark', 'light'] as const)('should return gradient colors for fixed color mode in %s theme', (mode) => { + expect( + buildGradientColors( + createTheme({ colors: { mode } }), + buildFieldDisplay(createField(FieldColorModeId.Fixed)), + '#442299' + ) + ).toMatchSnapshot(); + }); + }); + + describe('colorAtGradientPercent', () => { + it('should calculate the color at a given percent in a gradient of two colors', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#0000ff', percent: 1 }, + ]; + expect(colorAtGradientPercent(gradient, 0).toHexString()).toBe('#ff0000'); + expect(colorAtGradientPercent(gradient, 0.25).toHexString()).toBe('#bf0040'); + expect(colorAtGradientPercent(gradient, 0.5).toHexString()).toBe('#800080'); + expect(colorAtGradientPercent(gradient, 0.75).toHexString()).toBe('#4000bf'); + expect(colorAtGradientPercent(gradient, 1).toHexString()).toBe('#0000ff'); + }); + + it('should calculate the color at a given percent in a gradient of multiple colors', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + expect(colorAtGradientPercent(gradient, 0).toHexString()).toBe('#ff0000'); + expect(colorAtGradientPercent(gradient, 0.25).toHexString()).toBe('#808000'); + expect(colorAtGradientPercent(gradient, 0.5).toHexString()).toBe('#00ff00'); + expect(colorAtGradientPercent(gradient, 0.75).toHexString()).toBe('#008080'); + expect(colorAtGradientPercent(gradient, 1).toHexString()).toBe('#0000ff'); + }); + + it('will still work if unsorted', () => { + const gradient = [ + { color: '#0000ff', percent: 1 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#ff0000', percent: 0 }, + ]; + expect(colorAtGradientPercent(gradient, 0).toHexString()).toBe('#ff0000'); + expect(colorAtGradientPercent(gradient, 0.25).toHexString()).toBe('#808000'); + expect(colorAtGradientPercent(gradient, 0.5).toHexString()).toBe('#00ff00'); + expect(colorAtGradientPercent(gradient, 0.75).toHexString()).toBe('#008080'); + expect(colorAtGradientPercent(gradient, 1).toHexString()).toBe('#0000ff'); + }); + + it('should not throw an error when percent is outside 0-1 range', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#0000ff', percent: 1 }, + ]; + expect(colorAtGradientPercent(gradient, -0.5).toHexString()).toBe('#ff0000'); + expect(colorAtGradientPercent(gradient, 1.5).toHexString()).toBe('#0000ff'); + }); + + it('should throw an error when less than two stops are provided', () => { + expect(() => { + colorAtGradientPercent([], 0.5); + }).toThrow('colorAtGradientPercent requires at least two color stops'); + expect(() => { + colorAtGradientPercent([{ color: '#ff0000', percent: 0 }], 0.5); + }).toThrow('colorAtGradientPercent requires at least two color stops'); + }); + }); + + describe('getBarEndcapColors', () => { + it('should return the first and last colors in the gradient', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + const [startColor, endColor] = getBarEndcapColors(gradient); + expect(startColor).toBe('#ff0000'); + expect(endColor).toBe('#0000ff'); + }); + + it('should return the correct end color based on percent', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + const [startColor, endColor] = getBarEndcapColors(gradient, 0.25); + expect(startColor).toBe('#ff0000'); + expect(endColor).toBe('#808000'); + }); + + it('should handle gradients with only one colors', () => { + const gradient = [{ color: '#ff0000', percent: 0 }]; + const [startColor, endColor] = getBarEndcapColors(gradient); + expect(startColor).toBe('#ff0000'); + expect(endColor).toBe('#ff0000'); + }); + + it('should throw an error when no colors are provided', () => { + expect(() => { + getBarEndcapColors([]); + }).toThrow('getBarEndcapColors requires at least one color stop'); + }); + }); + + describe('getGradientCss', () => { + it('should return conic-gradient CSS for circle shape', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + const css = getGradientCss(gradient, 'circle'); + expect(css).toBe('conic-gradient(from 0deg, #ff0000 0.00%, #00ff00 50.00%, #0000ff 100.00%)'); + }); + + it('should return linear-gradient CSS for arc shape', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + const css = getGradientCss(gradient, 'gauge'); + expect(css).toBe('linear-gradient(90deg, #ff0000 0.00%, #00ff00 50.00%, #0000ff 100.00%)'); + }); + }); + + describe('getEndpointMarkerColors', () => { + it('should return contrasting guide dot colors based on the gradient endpoints and percent', () => { + const gradient = [ + { color: '#000000', percent: 0 }, + { color: '#ffffff', percent: 0.5 }, + { color: '#ffffff', percent: 1 }, + ]; + const [startDotColor, endDotColor] = getEndpointMarkerColors(gradient, 0.35); + expect(startDotColor).toBe('#fbfbfb'); + expect(endDotColor).toBe('#111217'); + }); + }); + + describe('getGradientStopsForPercent', () => { + it('should return the correct gradient stops for a given percent', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + const [left, right] = getGradientStopsForPercent(gradient, 0.25); + expect(left).toEqual({ color: '#ff0000', percent: 0 }); + expect(right).toEqual({ color: '#00ff00', percent: 0.5 }); + }); + + it('should handle edge cases where percent is at the boundaries', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + let [left, right] = getGradientStopsForPercent(gradient, 0); + expect(left).toEqual({ color: '#ff0000', percent: 0 }); + expect(right).toEqual({ color: '#ff0000', percent: 0 }); + + [left, right] = getGradientStopsForPercent(gradient, 1); + expect(left).toEqual({ color: '#0000ff', percent: 1 }); + expect(right).toEqual({ color: '#0000ff', percent: 1 }); + }); + + it('should return the same stop if there is one that is equal to the percentage', () => { + const gradient = [ + { color: '#ff0000', percent: 0 }, + { color: '#00ff00', percent: 0.5 }, + { color: '#0000ff', percent: 1 }, + ]; + + let [left, right] = getGradientStopsForPercent(gradient, 0); + expect(left).toEqual({ color: '#ff0000', percent: 0 }); + expect(right).toEqual({ color: '#ff0000', percent: 0 }); + + [left, right] = getGradientStopsForPercent(gradient, 0.5); + expect(left).toEqual({ color: '#00ff00', percent: 0.5 }); + expect(right).toEqual({ color: '#00ff00', percent: 0.5 }); + + [left, right] = getGradientStopsForPercent(gradient, 1); + expect(left).toEqual({ color: '#0000ff', percent: 1 }); + expect(right).toEqual({ color: '#0000ff', percent: 1 }); + }); + }); +}); diff --git a/packages/grafana-ui/src/components/RadialGauge/colors.ts b/packages/grafana-ui/src/components/RadialGauge/colors.ts new file mode 100644 index 00000000000..a05817a7a54 --- /dev/null +++ b/packages/grafana-ui/src/components/RadialGauge/colors.ts @@ -0,0 +1,187 @@ +import tinycolor from 'tinycolor2'; + +import { colorManipulator, FALLBACK_COLOR, FieldDisplay, getFieldColorMode, GrafanaTheme2 } from '@grafana/data'; +import { FieldColorModeId } from '@grafana/schema'; + +import { GradientStop, RadialShape } from './types'; +import { getFieldConfigMinMax, getFieldDisplayProcessor, getValuePercentageForValue } from './utils'; + +export function buildGradientColors( + theme: GrafanaTheme2, + fieldDisplay: FieldDisplay, + baseColor = fieldDisplay.display.color ?? FALLBACK_COLOR +): GradientStop[] { + const colorMode = getFieldColorMode(fieldDisplay.field.color?.mode); + + // thresholds get special handling + if (colorMode.id === FieldColorModeId.Thresholds) { + const displayProcessor = getFieldDisplayProcessor(fieldDisplay); + const [min, max] = getFieldConfigMinMax(fieldDisplay); + const thresholds = fieldDisplay.field.thresholds?.steps ?? []; + + const result: Array<{ color: string; percent: number }> = [ + { color: displayProcessor(min).color ?? baseColor, percent: 0 }, + ]; + + for (const threshold of thresholds) { + if (threshold.value > min && threshold.value < max) { + const percent = (threshold.value - min) / (max - min); + result.push({ color: theme.visualization.getColorByName(threshold.color), percent }); + } + } + + result.push({ color: displayProcessor(max).color ?? baseColor, percent: 1 }); + + return result; + } + + // Handle continuous color modes before other by-value modes + if (colorMode.isContinuous && colorMode.getColors) { + const colors = colorMode.getColors(theme); + return colors.map((color, idx) => ({ color, percent: idx / (colors.length - 1) })); + } + + // For value-based colors, we want to stay more true to the specific color, + // so a radial gradient that adds a bit of light and shade works best + if (colorMode.isByValue) { + const darkerColor = tinycolor(baseColor).darken(5); + const lighterColor = tinycolor(baseColor).spin(20).lighten(10); + + const color1 = theme.isDark ? lighterColor : darkerColor; + const color2 = theme.isDark ? darkerColor : lighterColor; + + return [ + { color: color1.toString(), percent: 0 }, + { color: color2.toString(), percent: 0.6 }, + { color: color2.toString(), percent: 1 }, + ]; + } + + // For fixed / palette based color scales we can create a more hue and light + // based linear gradient that we rotate with the value + const darkerColor = tinycolor(baseColor) + .spin(-20) + .darken(theme.isDark ? 15 : 5); + const lighterColor = tinycolor(baseColor).saturate(20).spin(20).brighten(10).lighten(10); + + const underlyingGradient = [ + { color: theme.isDark ? darkerColor.toString() : lighterColor.toString(), percent: 0 }, + { color: theme.isDark ? lighterColor.toString() : darkerColor.toString(), percent: 1 }, + ]; + + // rotate the gradient so that the highest contrasting point is the value, depending on theme. + const valuePercent = getValuePercentageForValue(fieldDisplay); + const startColor = theme.isDark + ? colorAtGradientPercent(underlyingGradient, 1 - valuePercent).toHexString() + : underlyingGradient[0].color; + const endColor = theme.isDark + ? underlyingGradient[1].color + : colorAtGradientPercent(underlyingGradient, valuePercent).toHexString(); + return [ + { color: startColor, percent: 0 }, + { color: endColor, percent: valuePercent }, + { color: endColor, percent: 1 }, + ]; +} + +/** + * get the relevant gradient stops surrounding a given percentage. could be same stop if the + * percent matches a stop exactly. + * + * @param sortedGradientStops - gradient stops sorted by percent + * @param percent - percentage 0..1 + * @returns {[GradientStop, GradientStop]} - the two gradient stops surrounding the given percentage + */ +export function getGradientStopsForPercent( + sortedGradientStops: GradientStop[], + percent: number +): [GradientStop, GradientStop] { + if (percent <= 0) { + return [sortedGradientStops[0], sortedGradientStops[0]]; + } + if (percent >= 1) { + const last = sortedGradientStops.length - 1; + return [sortedGradientStops[last], sortedGradientStops[last]]; + } + + // find surrounding stops using binary search + let lo = 0; + let hi = sortedGradientStops.length - 1; + while (lo + 1 < hi) { + const mid = (lo + hi) >> 1; + if (percent === sortedGradientStops[mid].percent) { + return [sortedGradientStops[mid], sortedGradientStops[mid]]; + } + + if (percent < sortedGradientStops[mid].percent) { + hi = mid; + } else { + lo = mid; + } + } + return [sortedGradientStops[lo], sortedGradientStops[hi]]; +} + +/** + * @alpha - perhaps this should go in colorManipulator.ts + * Given color stops (each with a color and percentage 0..1) returns the color at a given percentage. + * Uses tinycolor.mix for interpolation. + * @params stops - array of color stops (percentages 0..1) + * @params percent - percentage 0..1 + * @returns color at the given percentage + */ +export function colorAtGradientPercent(stops: GradientStop[], percent: number): tinycolor.Instance { + if (!stops || stops.length < 2) { + throw new Error('colorAtGradientPercent requires at least two color stops'); + } + + const sorted = stops + .map((s: GradientStop): GradientStop => ({ color: s.color, percent: Math.min(Math.max(0, s.percent), 1) })) + .sort((a: GradientStop, b: GradientStop) => a.percent - b.percent); + + const [left, right] = getGradientStopsForPercent(sorted, percent); + const range = right.percent - left.percent; + const t = range === 0 ? 0 : (percent - left.percent) / range; // 0..1 + return tinycolor.mix(left.color, right.color, t * 100); +} + +export function getBarEndcapColors(gradientStops: GradientStop[], percent = 1): [string, string] { + if (gradientStops.length === 0) { + throw new Error('getBarEndcapColors requires at least one color stop'); + } + + const startColor = gradientStops[0].color; + let endColor = gradientStops[gradientStops.length - 1].color; + + // if we have a percentageFilled, use it to get a the correct end color based on where the bar terminates + if (gradientStops.length >= 2) { + const endColorByPercentage = colorAtGradientPercent(gradientStops, percent); + endColor = + endColorByPercentage.getAlpha() === 1 ? endColorByPercentage.toHexString() : endColorByPercentage.toHex8String(); + } + return [startColor, endColor]; +} + +export function getGradientCss(gradientStops: GradientStop[], shape: RadialShape): string { + const colorStrings = gradientStops.map((stop) => `${stop.color} ${(stop.percent * 100).toFixed(2)}%`); + if (shape === 'circle') { + return `conic-gradient(from 0deg, ${colorStrings.join(', ')})`; + } + return `linear-gradient(90deg, ${colorStrings.join(', ')})`; +} + +// the theme does not make the full palette available to us, and we +// don't want transparent colors which our grays usually have. +const GRAY_05 = '#111217'; +const GRAY_90 = '#fbfbfb'; +const CONTRAST_THRESHOLD_MAX = 4.5; +export const getGuideDotColor = (color: string): string => { + const darkColor = GRAY_05; + const lightColor = GRAY_90; + return colorManipulator.getContrastRatio(darkColor, color) >= CONTRAST_THRESHOLD_MAX ? darkColor : lightColor; +}; + +export function getEndpointMarkerColors(gradientStops: GradientStop[], percent = 1): [string, string] { + const [startColor, endColor] = getBarEndcapColors(gradientStops, percent); + return [getGuideDotColor(startColor), getGuideDotColor(endColor)]; +} diff --git a/packages/grafana-ui/src/components/RadialGauge/effects.tsx b/packages/grafana-ui/src/components/RadialGauge/effects.tsx index 76f15900a14..2d3ae3daf21 100644 --- a/packages/grafana-ui/src/components/RadialGauge/effects.tsx +++ b/packages/grafana-ui/src/components/RadialGauge/effects.tsx @@ -1,14 +1,24 @@ -import { GrafanaTheme2 } from '@grafana/data'; +import { colorManipulator, GrafanaTheme2 } from '@grafana/data'; -import { GaugeDimensions } from './utils'; +import { RadialGaugeDimensions } from './types'; + +// some utility transparent white colors for gradients +const TRANSPARENT_WHITE = '#ffffff00'; +const MOSTLY_TRANSPARENT_WHITE = '#ffffff88'; +const MOSTLY_OPAQUE_WHITE = '#ffffffbb'; +const OPAQUE_WHITE = '#ffffff'; + +const MIN_GLOW_SIZE = 0.75; +const GLOW_FACTOR = 0.08; export interface GlowGradientProps { id: string; - radius: number; + barWidth: number; } -export function GlowGradient({ id, radius }: GlowGradientProps) { - const glowSize = 0.03 * radius; +export function GlowGradient({ id, barWidth }: GlowGradientProps) { + // 0.75 is the minimum glow size, and it scales with bar width + const glowSize = MIN_GLOW_SIZE + barWidth * GLOW_FACTOR; return ( @@ -21,69 +31,24 @@ export function GlowGradient({ id, radius }: GlowGradientProps) { ); } -export function SpotlightGradient({ - id, - dimensions, - roundedBars, - angle, - theme, -}: { - id: string; - dimensions: GaugeDimensions; - angle: number; - roundedBars: boolean; - theme: GrafanaTheme2; -}) { - const angleRadian = ((angle - 90) * Math.PI) / 180; - - let x1 = dimensions.centerX + dimensions.radius * Math.cos(angleRadian - 0.2); - let y1 = dimensions.centerY + dimensions.radius * Math.sin(angleRadian - 0.2); - let x2 = dimensions.centerX + dimensions.radius * Math.cos(angleRadian); - let y2 = dimensions.centerY + dimensions.radius * Math.sin(angleRadian); - - if (theme.isLight) { - return ( - - - - - - ); - } - - return ( - - - - {roundedBars && } - - ); -} - -export function CenterGlowGradient({ gaugeId, color }: { gaugeId: string; color: string }) { - return ( - - - - - ); -} +const CENTER_GLOW_OPACITY = 0.25; export interface CenterGlowProps { - dimensions: GaugeDimensions; + dimensions: RadialGaugeDimensions; gaugeId: string; color?: string; } export function MiddleCircleGlow({ dimensions, gaugeId, color }: CenterGlowProps) { const gradientId = `circle-glow-${gaugeId}`; + const transparentColor = color ? colorManipulator.alpha(color, CENTER_GLOW_OPACITY) : color; return ( <> - - - + + + @@ -92,3 +57,32 @@ export function MiddleCircleGlow({ dimensions, gaugeId, color }: CenterGlowProps ); } + +interface SpotlightGradientProps { + id: string; + dimensions: RadialGaugeDimensions; + angle: number; + roundedBars: boolean; + theme: GrafanaTheme2; +} + +export function SpotlightGradient({ id, dimensions, roundedBars, angle, theme }: SpotlightGradientProps) { + if (theme.isLight) { + return null; + } + + const angleRadian = ((angle - 90) * Math.PI) / 180; + + let x1 = dimensions.centerX + dimensions.radius * Math.cos(angleRadian - 0.2); + let y1 = dimensions.centerY + dimensions.radius * Math.sin(angleRadian - 0.2); + let x2 = dimensions.centerX + dimensions.radius * Math.cos(angleRadian); + let y2 = dimensions.centerY + dimensions.radius * Math.sin(angleRadian); + + return ( + + + + {roundedBars && } + + ); +} diff --git a/packages/grafana-ui/src/components/RadialGauge/types.ts b/packages/grafana-ui/src/components/RadialGauge/types.ts new file mode 100644 index 00000000000..111c7aef7d6 --- /dev/null +++ b/packages/grafana-ui/src/components/RadialGauge/types.ts @@ -0,0 +1,27 @@ +export type RadialTextMode = 'auto' | 'value_and_name' | 'value' | 'name' | 'none'; +export type RadialShape = 'circle' | 'gauge'; + +export interface RadialGaugeDimensions { + vizHeight: number; + vizWidth: number; + margin: number; + radius: number; + centerX: number; + centerY: number; + barWidth: number; + endAngle?: number; + barIndex: number; + thresholdsBarRadius: number; + thresholdsBarWidth: number; + thresholdsBarSpacing: number; + scaleLabelsFontSize: number; + scaleLabelsSpacing: number; + scaleLabelsRadius: number; + gaugeBottomY: number; +} + +/** @alpha - perhaps this should go in @grafana/data */ +export interface GradientStop { + color: string; + percent: number; +} diff --git a/packages/grafana-ui/src/components/RadialGauge/utils.test.ts b/packages/grafana-ui/src/components/RadialGauge/utils.test.ts index 5e3f34d62cd..70ee54a6337 100644 --- a/packages/grafana-ui/src/components/RadialGauge/utils.test.ts +++ b/packages/grafana-ui/src/components/RadialGauge/utils.test.ts @@ -1,24 +1,111 @@ -import { FieldDisplay } from '@grafana/data'; +import { DataFrameView, FieldDisplay } from '@grafana/data'; import type { RadialGaugeProps } from './RadialGauge'; -import { calculateDimensions, toRad, getValueAngleForValue } from './utils'; +import { RadialGaugeDimensions } from './types'; +import { + calculateDimensions, + toRad, + getValueAngleForValue, + drawRadialArcPath, + getFieldConfigMinMax, + getFieldDisplayProcessor, + getAngleBetweenSegments, + getOptimalSegmentCount, +} from './utils'; describe('RadialGauge utils', () => { - function calc(overrides: Partial = {}) { - return calculateDimensions( - overrides.width ?? 200, - overrides.height ?? 200, - overrides.shape === 'gauge' ? 110 : 360, - overrides.glowBar ?? false, - overrides.roundedBars ?? false, - overrides.barWidthFactor ?? 0.4, - overrides.barIndex ?? 0, - overrides.thresholdsBar ?? false, - overrides.showScaleLabels ?? false - ); - } + describe('getFieldDisplayProcessor', () => { + it('should return display processor from view when available', () => { + const mockProcessor = jest.fn(); + const mockView = { + getFieldDisplayProcessor: jest.fn().mockReturnValue(mockProcessor), + } as unknown as DataFrameView; + + const fieldDisplay: FieldDisplay = { + display: { numeric: 50, text: '50', color: 'blue' }, + field: {}, + view: mockView, + colIndex: 0, + rowIndex: 0, + name: 'test', + getLinks: () => [], + hasLinks: false, + }; + + const dp = getFieldDisplayProcessor(fieldDisplay); + expect(dp).toBe(mockProcessor); + expect(mockView.getFieldDisplayProcessor).toHaveBeenCalledWith(0); + }); + + it('should return default display processor when view is not available', () => { + const fieldDisplay: FieldDisplay = { + display: { numeric: 50, text: '50', color: 'blue' }, + field: {}, + view: undefined, + colIndex: 0, + rowIndex: 0, + name: 'test', + getLinks: () => [], + hasLinks: false, + }; + + const dp = getFieldDisplayProcessor(fieldDisplay); + expect(dp).toBeDefined(); + expect(typeof dp).toBe('function'); + }); + }); + + describe('getFieldConfigMinMax', () => { + it('should return min and max from field config when defined', () => { + const fieldDisplay: FieldDisplay = { + display: { numeric: 50, text: '50', color: 'blue' }, + field: { min: 10, max: 90 }, + view: undefined, + colIndex: 0, + rowIndex: 0, + name: 'test', + getLinks: () => [], + hasLinks: false, + }; + + const [min, max] = getFieldConfigMinMax(fieldDisplay); + expect(min).toBe(10); + expect(max).toBe(90); + }); + + it('should return default min and max when not defined in field config', () => { + const fieldDisplay: FieldDisplay = { + display: { numeric: 50, text: '50', color: 'blue' }, + field: {}, + view: undefined, + colIndex: 0, + rowIndex: 0, + name: 'test', + getLinks: () => [], + hasLinks: false, + }; + + const [min, max] = getFieldConfigMinMax(fieldDisplay); + expect(min).toBe(0); + expect(max).toBe(100); + }); + }); describe('calculateDimensions', () => { + function calc(overrides: Partial = {}) { + return calculateDimensions( + overrides.width ?? 200, + overrides.height ?? 200, + overrides.shape === 'gauge' ? 110 : 360, + overrides.glowBar ?? false, + overrides.roundedBars ?? false, + overrides.barWidthFactor ?? 0.4, + overrides.barIndex ?? 0, + overrides.thresholdsBar ?? false, + overrides.showScaleLabels ?? false + ); + } + it('should calculate basic dimensions for a square gauge', () => { const result = calc(); @@ -194,4 +281,83 @@ describe('RadialGauge utils', () => { expect(result.angle).toBe(240); }); }); + + describe('drawRadialArcPath', () => { + const defaultDims = Object.freeze({ + vizHeight: 220, + vizWidth: 220, + centerX: 100, + centerY: 100, + radius: 80, + barWidth: 20, + margin: 0, + barIndex: 0, + thresholdsBarWidth: 0, + thresholdsBarSpacing: 0, + thresholdsBarRadius: 0, + scaleLabelsFontSize: 0, + scaleLabelsSpacing: 0, + scaleLabelsRadius: 0, + gaugeBottomY: 0, + }) satisfies RadialGaugeDimensions; + + it.each([ + { description: 'quarter arc', startAngle: 0, endAngle: 90 }, + { description: 'half arc', startAngle: 0, endAngle: 180 }, + { description: 'three quarter arc', startAngle: 0, endAngle: 270 }, + { description: 'rounded bars', startAngle: 0, endAngle: 270, roundedBars: true }, + { description: 'wide bar width', startAngle: 0, endAngle: 180, dimensions: { barWidth: 50 } }, + { description: 'narrow bar width', startAngle: 0, endAngle: 180, dimensions: { barWidth: 5 } }, + { description: 'narrow radius', startAngle: 0, endAngle: 180, dimensions: { radius: 50 } }, + { + description: 'center x and y', + startAngle: 0, + endAngle: 360, + roundedBars: true, + dimensions: { centerX: 150, centerY: 200 }, + }, + ])(`should draw correct path for $description`, ({ startAngle, endAngle, dimensions, roundedBars }) => { + const path = drawRadialArcPath(startAngle, endAngle, { ...defaultDims, ...dimensions }, roundedBars); + expect(path).toMatchSnapshot(); + }); + + describe('edge cases', () => { + it('should adjust 360deg or greater arcs to avoid SVG rendering issues', () => { + expect(drawRadialArcPath(0, 360, defaultDims)).toEqual(drawRadialArcPath(0, 359.99, defaultDims)); + expect(drawRadialArcPath(0, 380, defaultDims)).toEqual(drawRadialArcPath(0, 380, defaultDims)); + }); + }); + }); + + describe('getAngleBetweenSegments', () => { + it('should calculate angle between segments based on spacing and count', () => { + expect(getAngleBetweenSegments(2, 10, 360)).toBe(48); + expect(getAngleBetweenSegments(5, 15, 180)).toBe(40); + }); + }); + + describe('getOptimalSegmentCount', () => { + it('should adjust segment count based on dimensions and spacing', () => { + const dimensions = { + vizHeight: 220, + vizWidth: 220, + centerX: 100, + centerY: 100, + radius: 80, + barWidth: 20, + margin: 0, + barIndex: 0, + thresholdsBarWidth: 0, + thresholdsBarSpacing: 0, + thresholdsBarRadius: 0, + scaleLabelsFontSize: 0, + scaleLabelsSpacing: 0, + scaleLabelsRadius: 0, + gaugeBottomY: 0, + } satisfies RadialGaugeDimensions; + + expect(getOptimalSegmentCount(dimensions, 2, 10, 360)).toBe(8); + expect(getOptimalSegmentCount(dimensions, 1, 5, 360)).toBe(5); + }); + }); }); diff --git a/packages/grafana-ui/src/components/RadialGauge/utils.ts b/packages/grafana-ui/src/components/RadialGauge/utils.ts index 44f767d89b2..a18efc42699 100644 --- a/packages/grafana-ui/src/components/RadialGauge/utils.ts +++ b/packages/grafana-ui/src/components/RadialGauge/utils.ts @@ -1,11 +1,38 @@ -import { FieldDisplay } from '@grafana/data'; +import { FieldDisplay, getDisplayProcessor } from '@grafana/data'; -export function getValueAngleForValue(fieldDisplay: FieldDisplay, startAngle: number, endAngle: number) { - const angleRange = (360 % (startAngle === 0 ? 1 : startAngle)) + endAngle; +import { RadialGaugeDimensions } from './types'; + +export function getFieldDisplayProcessor(displayValue: FieldDisplay) { + if (displayValue.view && displayValue.colIndex != null) { + const dp = displayValue.view.getFieldDisplayProcessor(displayValue.colIndex); + if (dp) { + return dp; + } + } + + return getDisplayProcessor(); +} + +export function getFieldConfigMinMax(fieldDisplay: FieldDisplay) { const min = fieldDisplay.field.min ?? 0; const max = fieldDisplay.field.max ?? 100; + return [min, max]; +} - let angle = ((fieldDisplay.display.numeric - min) / (max - min)) * angleRange; +export function getValuePercentageForValue(fieldDisplay: FieldDisplay, value = fieldDisplay.display.numeric) { + const [min, max] = getFieldConfigMinMax(fieldDisplay); + return (value - min) / (max - min); +} + +export function getValueAngleForValue( + fieldDisplay: FieldDisplay, + startAngle: number, + endAngle: number, + value = fieldDisplay.display.numeric +) { + const angleRange = (360 % (startAngle === 0 ? 1 : startAngle)) + endAngle; + + let angle = getValuePercentageForValue(fieldDisplay, value) * angleRange; if (angle > angleRange) { angle = angleRange; @@ -26,24 +53,19 @@ export function toRad(angle: number) { return ((angle - 90) * Math.PI) / 180; } -export interface GaugeDimensions { - margin: number; - radius: number; - centerX: number; - centerY: number; - barWidth: number; - endAngle?: number; - barIndex: number; - thresholdsBarRadius: number; - thresholdsBarWidth: number; - thresholdsBarSpacing: number; - showScaleLabels?: boolean; - scaleLabelsFontSize: number; - scaleLabelsSpacing: number; - scaleLabelsRadius: number; - gaugeBottomY: number; -} - +/** + * returns the calculated dimensions for the radial gauge + * @param width + * @param height + * @param endAngle + * @param glow + * @param roundedBars + * @param barWidthFactor + * @param barIndex + * @param thresholdBar + * @param showScaleLabels + * @returns {RadialGaugeDimensions} + */ export function calculateDimensions( width: number, height: number, @@ -54,7 +76,7 @@ export function calculateDimensions( barIndex: number, thresholdBar?: boolean, showScaleLabels?: boolean -): GaugeDimensions { +): RadialGaugeDimensions { const yMaxAngle = endAngle > 180 ? 180 : endAngle; let margin = 0; @@ -97,6 +119,7 @@ export function calculateDimensions( maxRadiusW -= labelsSize; maxRadiusH -= labelsSize; + // FIXME: needs coverage // For gauges the max label needs a bit more vertical space so that it does not get clipped if (maxRadiusIsLimitedByHeight && endAngle < 180) { const amount = outerRadius * 0.07; @@ -132,6 +155,8 @@ export function calculateDimensions( } return { + vizWidth: width, + vizHeight: height, margin, gaugeBottomY: centerY + belowCenterY, radius: innerRadius, @@ -155,3 +180,51 @@ export function toCartesian(centerX: number, centerY: number, radius: number, an y: centerY + radius * Math.sin(radian), }; } + +export function drawRadialArcPath( + startAngle: number, + endAngle: number, + dimensions: RadialGaugeDimensions, + roundedBars?: boolean +): string { + const { radius, centerX, centerY } = dimensions; + + // For some reason a 100% full arc cannot be rendered + if (endAngle >= 360) { + endAngle = 359.99; + } + + const startRadians = toRad(startAngle); + const endRadians = toRad(startAngle + endAngle); + + const largeArc = endAngle > 180 ? 1 : 0; + + let x1 = centerX + radius * Math.cos(startRadians); + let y1 = centerY + radius * Math.sin(startRadians); + let x2 = centerX + radius * Math.cos(endRadians); + let y2 = centerY + radius * Math.sin(endRadians); + + return ['M', x1, y1, 'A', radius, radius, 0, largeArc, 1, x2, y2].join(' '); +} + +export function getAngleBetweenSegments(segmentSpacing: number, segmentCount: number, range: number) { + // Max spacing is 8 degrees between segments + // Changing this constant could be considered a breaking change + const maxAngleBetweenSegments = Math.max(range / 1.5 / segmentCount, 2); + return segmentSpacing * maxAngleBetweenSegments; +} + +export function getOptimalSegmentCount( + dimensions: RadialGaugeDimensions, + segmentSpacing: number, + segmentCount: number, + range: number +) { + const angleBetweenSegments = getAngleBetweenSegments(segmentSpacing, segmentCount, range); + + const innerRadius = dimensions.radius - dimensions.barWidth / 2; + const circumference = Math.PI * innerRadius * 2 * (range / 360); + const maxSegments = Math.floor(circumference / (angleBetweenSegments + 3)); + + return Math.min(maxSegments, segmentCount); +} diff --git a/packages/grafana-ui/src/components/Select/ValueContainer.tsx b/packages/grafana-ui/src/components/Select/ValueContainer.tsx index 6eb8326ae5d..f39666c8c5f 100644 --- a/packages/grafana-ui/src/components/Select/ValueContainer.tsx +++ b/packages/grafana-ui/src/components/Select/ValueContainer.tsx @@ -76,4 +76,5 @@ class UnthemedValueContainer>> = + withTheme2(UnthemedValueContainer); diff --git a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts index 90ac3877c2a..1432c01e1da 100644 --- a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts +++ b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts @@ -1,9 +1,9 @@ import { useMemo } from 'react'; -import { CSSObjectWithLabel } from 'react-select'; +import { StylesConfig } from 'react-select'; import { GrafanaTheme2 } from '@grafana/data'; -export default function resetSelectStyles(theme: GrafanaTheme2) { +export default function resetSelectStyles(theme: GrafanaTheme2): Partial { return { clearIndicator: () => ({}), container: () => ({}), @@ -13,7 +13,7 @@ export default function resetSelectStyles(theme: GrafanaTheme2) { groupHeading: () => ({}), indicatorsContainer: () => ({}), indicatorSeparator: () => ({}), - input: function (originalStyles: CSSObjectWithLabel) { + input: function (originalStyles) { return { ...originalStyles, color: 'inherit', @@ -27,7 +27,7 @@ export default function resetSelectStyles(theme: GrafanaTheme2) { loadingIndicator: () => ({}), loadingMessage: () => ({}), menu: () => ({}), - menuList: ({ maxHeight }: { maxHeight: number }) => ({ + menuList: ({ maxHeight }) => ({ maxHeight, }), multiValue: () => ({}), @@ -38,7 +38,7 @@ export default function resetSelectStyles(theme: GrafanaTheme2) { multiValueRemove: () => ({}), noOptionsMessage: () => ({}), option: () => ({}), - placeholder: (originalStyles: CSSObjectWithLabel) => ({ + placeholder: (originalStyles) => ({ ...originalStyles, color: theme.colors.text.secondary, }), @@ -47,11 +47,11 @@ export default function resetSelectStyles(theme: GrafanaTheme2) { }; } -export function useCustomSelectStyles(theme: GrafanaTheme2, width: number | string | undefined) { +export function useCustomSelectStyles(theme: GrafanaTheme2, width: number | string | undefined): Partial { return useMemo(() => { return { ...resetSelectStyles(theme), - menuPortal: (base: CSSObjectWithLabel) => { + menuPortal: (base) => { // Would like to correct top position when menu is placed bottom, but have props are not sent to this style function. // Only state is. https://github.com/JedWatson/react-select/blob/master/packages/react-select/src/components/Menu.tsx#L605 return { @@ -60,7 +60,7 @@ export function useCustomSelectStyles(theme: GrafanaTheme2, width: number | stri }; }, //These are required for the menu positioning to function - menu: ({ top, bottom, position }: CSSObjectWithLabel) => { + menu: ({ top, bottom, position }) => { return { top, bottom, @@ -73,7 +73,7 @@ export function useCustomSelectStyles(theme: GrafanaTheme2, width: number | stri width: width ? theme.spacing(width) : '100%', display: width === 'auto' ? 'inline-flex' : 'flex', }), - option: (provided: CSSObjectWithLabel, state: any) => ({ + option: (provided, state) => ({ ...provided, opacity: state.isDisabled ? 0.5 : 1, }), diff --git a/packages/grafana-ui/src/components/Sparkline/Sparkline.test.tsx b/packages/grafana-ui/src/components/Sparkline/Sparkline.test.tsx index 9ad678132e9..91f3d9945f3 100644 --- a/packages/grafana-ui/src/components/Sparkline/Sparkline.test.tsx +++ b/packages/grafana-ui/src/components/Sparkline/Sparkline.test.tsx @@ -27,4 +27,48 @@ describe('Sparkline', () => { render() ).not.toThrow(); }); + + it('should not throw an error if there is a single value', () => { + const sparkline: FieldSparkline = { + x: { + name: 'x', + values: [1679839200000], + type: FieldType.time, + config: {}, + }, + y: { + name: 'y', + values: [1], + type: FieldType.number, + config: {}, + state: { + range: { min: 1, max: 1, delta: 0 }, + }, + }, + }; + expect(() => + render() + ).not.toThrow(); + }); + + it('should not throw an error if there are no values', () => { + const sparkline: FieldSparkline = { + x: { + name: 'x', + values: [], + type: FieldType.time, + config: {}, + }, + y: { + name: 'y', + values: [], + type: FieldType.number, + config: {}, + state: {}, + }, + }; + expect(() => + render() + ).not.toThrow(); + }); }); diff --git a/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx b/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx index 8de8ed1b893..a9d3f039c42 100644 --- a/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx +++ b/packages/grafana-ui/src/components/Sparkline/Sparkline.tsx @@ -1,203 +1,34 @@ -import { isEqual } from 'lodash'; -import { PureComponent } from 'react'; -import { AlignedData, Range } from 'uplot'; +import React, { memo } from 'react'; -import { - compareDataFrameStructures, - DataFrame, - Field, - FieldConfig, - FieldSparkline, - FieldType, - getFieldColorModeForField, - nullToValue, -} from '@grafana/data'; -import { - AxisPlacement, - GraphDrawStyle, - GraphFieldConfig, - VisibilityMode, - ScaleDirection, - ScaleOrientation, -} from '@grafana/schema'; +import { FieldConfig, FieldSparkline } from '@grafana/data'; +import { GraphFieldConfig } from '@grafana/schema'; import { Themeable2 } from '../../types/theme'; import { UPlotChart } from '../uPlot/Plot'; -import { UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; import { preparePlotData2, getStackingGroups } from '../uPlot/utils'; -import { getYRange, preparePlotFrame } from './utils'; +import { prepareSeries, prepareConfig } from './utils'; export interface SparklineProps extends Themeable2 { width: number; height: number; config?: FieldConfig; sparkline: FieldSparkline; + showHighlights?: boolean; } -interface State { - data: AlignedData; - alignedDataFrame: DataFrame; - configBuilder: UPlotConfigBuilder; -} +export const Sparkline: React.FC = memo((props) => { + const { sparkline, config: fieldConfig, theme, width, height, showHighlights } = props; -const defaultConfig: GraphFieldConfig = { - drawStyle: GraphDrawStyle.Line, - showPoints: VisibilityMode.Auto, - axisPlacement: AxisPlacement.Hidden, - pointSize: 2, -}; - -/** @internal */ -export class Sparkline extends PureComponent { - constructor(props: SparklineProps) { - super(props); - - const alignedDataFrame = preparePlotFrame(props.sparkline, props.config); - - this.state = { - data: preparePlotData2(alignedDataFrame, getStackingGroups(alignedDataFrame)), - alignedDataFrame, - configBuilder: this.prepareConfig(alignedDataFrame), - }; + const { frame: alignedDataFrame, warning } = prepareSeries(sparkline, theme, fieldConfig, showHighlights); + if (warning) { + return null; } - static getDerivedStateFromProps(props: SparklineProps, state: State) { - const _frame = preparePlotFrame(props.sparkline, props.config); - const frame = nullToValue(_frame); - if (!frame) { - return { ...state }; - } + const data = preparePlotData2(alignedDataFrame, getStackingGroups(alignedDataFrame)); + const configBuilder = prepareConfig(sparkline, alignedDataFrame, theme, showHighlights); - return { - ...state, - data: preparePlotData2(frame, getStackingGroups(frame)), - alignedDataFrame: frame, - }; - } + return ; +}); - componentDidUpdate(prevProps: SparklineProps, prevState: State) { - const { alignedDataFrame } = this.state; - - if (!alignedDataFrame) { - return; - } - - let rebuildConfig = false; - - if (prevProps.sparkline !== this.props.sparkline) { - const isStructureChanged = !compareDataFrameStructures(this.state.alignedDataFrame, prevState.alignedDataFrame); - const isRangeChanged = !isEqual( - alignedDataFrame.fields[1].state?.range, - prevState.alignedDataFrame.fields[1].state?.range - ); - rebuildConfig = isStructureChanged || isRangeChanged; - } else { - rebuildConfig = !isEqual(prevProps.config, this.props.config); - } - - if (rebuildConfig) { - this.setState({ configBuilder: this.prepareConfig(alignedDataFrame) }); - } - } - - getYRange(field: Field): Range.MinMax { - return getYRange(field, this.state.alignedDataFrame); - } - - prepareConfig(data: DataFrame) { - const { theme } = this.props; - const builder = new UPlotConfigBuilder(); - - builder.setCursor({ - show: false, - x: false, // no crosshairs - y: false, - }); - - // X is the first field in the alligned frame - const xField = data.fields[0]; - builder.addScale({ - scaleKey: 'x', - orientation: ScaleOrientation.Horizontal, - direction: ScaleDirection.Right, - isTime: false, //xField.type === FieldType.time, - range: () => { - const { sparkline } = this.props; - if (sparkline.x) { - if (sparkline.timeRange && sparkline.x.type === FieldType.time) { - return [sparkline.timeRange.from.valueOf(), sparkline.timeRange.to.valueOf()]; - } - const vals = sparkline.x.values; - return [vals[0], vals[vals.length - 1]]; - } - return [0, sparkline.y.values.length - 1]; - }, - }); - - builder.addAxis({ - scaleKey: 'x', - theme, - placement: AxisPlacement.Hidden, - }); - - for (let i = 0; i < data.fields.length; i++) { - const field = data.fields[i]; - const config: FieldConfig = field.config; - const customConfig: GraphFieldConfig = { - ...defaultConfig, - ...config.custom, - }; - - if (field === xField || field.type !== FieldType.number) { - continue; - } - - const scaleKey = config.unit || '__fixed'; - builder.addScale({ - scaleKey, - orientation: ScaleOrientation.Vertical, - direction: ScaleDirection.Up, - range: () => this.getYRange(field), - }); - - builder.addAxis({ - scaleKey, - theme, - placement: AxisPlacement.Hidden, - }); - - const colorMode = getFieldColorModeForField(field); - const seriesColor = colorMode.getCalculator(field, theme)(0, 0); - const pointsMode = - customConfig.drawStyle === GraphDrawStyle.Points ? VisibilityMode.Always : customConfig.showPoints; - - builder.addSeries({ - pxAlign: false, - scaleKey, - theme, - colorMode, - thresholds: config.thresholds, - drawStyle: customConfig.drawStyle!, - lineColor: customConfig.lineColor ?? seriesColor, - lineWidth: customConfig.lineWidth, - lineInterpolation: customConfig.lineInterpolation, - showPoints: pointsMode, - pointSize: customConfig.pointSize, - fillOpacity: customConfig.fillOpacity, - fillColor: customConfig.fillColor, - lineStyle: customConfig.lineStyle, - gradientMode: customConfig.gradientMode, - spanNulls: customConfig.spanNulls, - }); - } - - return builder; - } - - render() { - const { data, configBuilder } = this.state; - const { width, height } = this.props; - return ; - } -} +Sparkline.displayName = 'Sparkline'; diff --git a/packages/grafana-ui/src/components/Sparkline/utils.test.ts b/packages/grafana-ui/src/components/Sparkline/utils.test.ts index 9eb914af438..0ec65515e0c 100644 --- a/packages/grafana-ui/src/components/Sparkline/utils.test.ts +++ b/packages/grafana-ui/src/components/Sparkline/utils.test.ts @@ -1,6 +1,6 @@ -import { Field, FieldSparkline, FieldType } from '@grafana/data'; +import { createTheme, Field, FieldSparkline, FieldType, toDataFrame } from '@grafana/data'; -import { getYRange, preparePlotFrame } from './utils'; +import { getYRange, prepareConfig, preparePlotFrame } from './utils'; describe('Prepare Sparkline plot frame', () => { it('should return sorted array if x-axis numeric', () => { @@ -114,6 +114,20 @@ describe('Get y range', () => { config: {}, state: { range: { min: -2, max: -2, delta: 0 } }, }; + const decimalsCloseYField: Field = { + name: 'y', + values: [2, 1.999999999999999, 2.000000000000001, 2, 2], + type: FieldType.number, + config: {}, + state: { range: { min: 1.9999999999999999999, max: 2.000000000000000001, delta: 0 } }, + }; + const decimalsNotCloseYField: Field = { + name: 'y', + values: [2, 0.0094, 0.0053, 0.0078, 0.0061], + type: FieldType.number, + config: {}, + state: { range: { min: 0.0053, max: 0.0094, delta: 0.0041 } }, + }; const xField: Field = { name: 'x', values: [1000, 2000, 3000, 4000, 5000], @@ -154,12 +168,12 @@ describe('Get y range', () => { { description: 'straight line', field: straightLineYField, - expected: [0, 4], + expected: [2, 4], }, { description: 'straight line, negative values', field: straightLineNegYField, - expected: [-4, 0], + expected: [-4, -2], }, { description: 'straight line with config min and max', @@ -171,9 +185,150 @@ describe('Get y range', () => { field: { ...straightLineYField, config: { noValue: '0' } }, expected: [0, 2], }, + { + description: 'long decimals which are nearly equal and result in a functional delta of 0', + field: decimalsCloseYField, + expected: [2, 4], + }, + { + description: 'decimal values which are not close to equal should not be rounded out', + field: decimalsNotCloseYField, + expected: [0.0053, 0.0094], + }, ])(`should return correct range for $description`, ({ field, expected }) => { - const actual = getYRange(field, getAlignedFrame(field)); + const actual = getYRange(getAlignedFrame(field)); expect(actual).toEqual(expected); expect(actual[0]).toBeLessThan(actual[1]!); }); }); + +describe('prepareConfig', () => { + it('should not throw an error if there are multiple values', () => { + const sparkline: FieldSparkline = { + x: { + name: 'x', + values: [1679839200000, 1680444000000, 1681048800000, 1681653600000, 1682258400000], + type: FieldType.time, + config: {}, + }, + y: { + name: 'y', + values: [1, 2, 3, 4, 5], + type: FieldType.number, + config: {}, + }, + }; + + const dataFrame = toDataFrame({ + fields: [sparkline.x, sparkline.y], + }); + + const config = prepareConfig(sparkline, dataFrame, createTheme()); + expect(config.series.length).toBe(1); + }); + + it('should not throw an error if there is a single value', () => { + const sparkline: FieldSparkline = { + x: { + name: 'x', + values: [1679839200000], + type: FieldType.time, + config: {}, + }, + y: { + name: 'y', + values: [1], + type: FieldType.number, + config: {}, + }, + }; + + const dataFrame = toDataFrame({ + fields: [sparkline.x, sparkline.y], + }); + + const config = prepareConfig(sparkline, dataFrame, createTheme()); + expect(config.series.length).toBe(1); + }); + + it('should not throw an error if there are no values', () => { + const sparkline: FieldSparkline = { + x: { + name: 'x', + values: [], + type: FieldType.time, + config: {}, + }, + y: { + name: 'y', + values: [], + type: FieldType.number, + config: {}, + }, + }; + + const dataFrame = toDataFrame({ + fields: [sparkline.x, sparkline.y], + }); + + const config = prepareConfig(sparkline, dataFrame, createTheme()); + expect(config.series.length).toBe(1); + }); + + it('should set up highlight series if showHighlights is true and highlightIdx exists', () => { + const sparkline: FieldSparkline = { + x: { + name: 'x', + values: [1679839200000, 1680444000000, 1681048800000, 1681653600000, 1682258400000], + type: FieldType.time, + config: {}, + }, + y: { + name: 'y', + values: [1, 2, 3, 4, 5], + type: FieldType.number, + config: {}, + }, + highlightIndex: 2, + }; + + const dataFrame = toDataFrame({ + fields: [sparkline.x, sparkline.y], + }); + + const config = prepareConfig(sparkline, dataFrame, createTheme(), true); + expect(config.series.length).toBe(1); + expect(config.series[0].getConfig().points).toEqual( + expect.objectContaining({ + show: true, + filter: [2], + }) + ); + }); + + it('should not set up highlight series if showHighlights is false even if highlightIdx exists', () => { + const sparkline: FieldSparkline = { + x: { + name: 'x', + values: [1679839200000, 1680444000000, 1681048800000, 1681653600000, 1682258400000], + type: FieldType.time, + config: {}, + }, + y: { + name: 'y', + values: [1, 2, 3, 4, 5], + type: FieldType.number, + config: {}, + }, + highlightIndex: 2, + }; + + const dataFrame = toDataFrame({ + fields: [sparkline.x, sparkline.y], + }); + + const config = prepareConfig(sparkline, dataFrame, createTheme(), false); + expect(config.series.length).toBe(1); + expect(config.series[0].getConfig().points?.show).not.toBe(true); + }); +}); diff --git a/packages/grafana-ui/src/components/Sparkline/utils.ts b/packages/grafana-ui/src/components/Sparkline/utils.ts index 5c2afd8a1cb..cb7259ce7d0 100644 --- a/packages/grafana-ui/src/components/Sparkline/utils.ts +++ b/packages/grafana-ui/src/components/Sparkline/utils.ts @@ -1,16 +1,32 @@ import { Range } from 'uplot'; import { + applyNullInsertThreshold, + // colorManipulator, DataFrame, FieldConfig, FieldSparkline, FieldType, + getFieldColorModeForField, + GrafanaTheme2, + guessDecimals, isLikelyAscendingVector, + nullToValue, + roundDecimals, sortDataFrame, - applyNullInsertThreshold, - Field, } from '@grafana/data'; -import { GraphFieldConfig } from '@grafana/schema'; +import { t } from '@grafana/i18n'; +import { + AxisPlacement, + GraphDrawStyle, + GraphFieldConfig, + VisibilityMode, + ScaleDirection, + ScaleOrientation, + // FieldColorModeId, +} from '@grafana/schema'; + +import { UPlotConfigBuilder } from '../uPlot/config/UPlotConfigBuilder'; /** @internal * Given a sparkline config returns a DataFrame ready to be turned into Plot data set @@ -55,33 +71,202 @@ export function preparePlotFrame(sparkline: FieldSparkline, config?: FieldConfig /** * apply configuration defaults and ensure that the range is never two equal values. */ -export function getYRange(field: Field, alignedFrame: DataFrame): Range.MinMax { - let { min, max } = alignedFrame.fields[1].state?.range!; +export function getYRange(alignedFrame: DataFrame): Range.MinMax { + const field = alignedFrame.fields[1]; + let { min, max } = field.state?.range!; - // enure that the min/max from the field config are respected - min = Math.max(min!, field.config.min ?? -Infinity); - max = Math.min(max!, field.config.max ?? Infinity); + // enure that the min/max from the field config are respected. + min = Math.min(min!, field.config.min ?? Infinity); + max = Math.max(max!, field.config.max ?? -Infinity); // if noValue is set, ensure that it is included in the range as well - const noValue = +alignedFrame.fields[1].config?.noValue!; + const noValue = +field.config?.noValue!; if (!Number.isNaN(noValue)) { min = Math.min(min, noValue); max = Math.max(max, noValue); } - // if min and max are equal after all of that, create a range - // that allows the sparkline to be visible in the center of the viz - if (min === max) { - if (min === 0) { - max = 100; - } else if (min < 0) { - max = 0; - min *= 2; - } else { - min = 0; - max *= 2; - } + const decimals = field.config.decimals ?? Math.max(guessDecimals(min), guessDecimals(max)); + + // call roundDecimals to mirror what is going to eventually happen in uplot + let roundedMin = roundDecimals(min, decimals); + let roundedMax = roundDecimals(max, decimals); + + // if the rounded min and max are different, + // we can return the real min and max. + if (roundedMin !== roundedMax) { + return [min, max]; } - return [min, max]; + // we are forced to tweak the min and max since they + // will be treated as equal after rounding by uPlot. + if (roundedMin === 0) { + // both are zero + roundedMax = 1; + } else if (roundedMin < 0) { + // both are negative + roundedMin *= 2; + } else { + // both are positive + roundedMax *= 2; + } + + return [roundedMin, roundedMax]; } + +const HIGHLIGHT_IDX_POINT_SIZE = 6; + +const defaultConfig: GraphFieldConfig = { + drawStyle: GraphDrawStyle.Line, + showPoints: VisibilityMode.Auto, + axisPlacement: AxisPlacement.Hidden, + pointSize: 0, +}; + +export const prepareSeries = ( + sparkline: FieldSparkline, + _theme: GrafanaTheme2, + fieldConfig?: FieldConfig, + _showHighlights?: boolean +): { frame: DataFrame; warning?: string } => { + const frame = nullToValue(preparePlotFrame(sparkline, fieldConfig)); + if (frame.fields.some((f) => f.values.length <= 1)) { + return { + warning: t( + 'grafana-ui.components.sparkline.warning.too-few-values', + 'Sparkline requires at least two values to render.' + ), + frame, + }; + } + // TODO:rgb(24, 24, 24) will address this. + // if (showHighlights && typeof sparkline.highlightLine === 'number') { + // const highlightY = sparkline.highlightLine; + // const colorMode = getFieldColorModeForField(sparkline.y); + // const seriesColor = colorMode.getCalculator(sparkline.y, theme)(highlightY, 0); + // frame.fields.push({ + // name: 'highlightLine', + // type: FieldType.number, + // values: new Array(frame.length).fill(highlightY), + // config: { + // color: { + // mode: FieldColorModeId.Fixed, + // fixedColor: colorManipulator.lighten(seriesColor, 0.5), + // }, + // custom: { + // lineStyle: { + // fill: 'dash', + // dash: [5, 2], + // }, + // }, + // }, + // state: {}, + // }); + // } + return { frame }; +}; + +export const prepareConfig = ( + sparkline: FieldSparkline, + dataFrame: DataFrame, + theme: GrafanaTheme2, + showHighlights?: boolean +): UPlotConfigBuilder => { + const builder = new UPlotConfigBuilder(); + const rangePad = HIGHLIGHT_IDX_POINT_SIZE / 2; + + builder.setCursor({ + show: false, + x: false, // no crosshairs + y: false, + }); + + // X is the first field in the aligned frame + const xField = dataFrame.fields[0]; + builder.addScale({ + scaleKey: 'x', + orientation: ScaleOrientation.Horizontal, + direction: ScaleDirection.Right, + isTime: false, // xField.type === FieldType.time, + range: () => { + if (sparkline.x) { + if (sparkline.timeRange && sparkline.x.type === FieldType.time) { + return [sparkline.timeRange.from.valueOf(), sparkline.timeRange.to.valueOf()]; + } + const vals = sparkline.x.values; + return [vals[0], vals[vals.length - 1]]; + } + return [0, sparkline.y.values.length - 1]; + }, + }); + + builder.addAxis({ + scaleKey: 'x', + theme, + placement: AxisPlacement.Hidden, + show: false, + }); + + for (let i = 0; i < dataFrame.fields.length; i++) { + const field = dataFrame.fields[i]; + const config: FieldConfig = field.config; + const customConfig: GraphFieldConfig = { + ...defaultConfig, + ...config.custom, + }; + + if (field === xField || field.type !== FieldType.number) { + continue; + } + + const scaleKey = config.unit || '__fixed'; + builder.addScale({ + scaleKey, + orientation: ScaleOrientation.Vertical, + direction: ScaleDirection.Up, + range: () => getYRange(dataFrame), + }); + + builder.addAxis({ + scaleKey, + theme, + placement: AxisPlacement.Hidden, + show: false, + }); + + const colorMode = getFieldColorModeForField(field); + const seriesColor = colorMode.getCalculator(field, theme)(0, 0); + + const hasHighlightIndex = showHighlights && typeof sparkline.highlightIndex === 'number'; + if (hasHighlightIndex) { + builder.setPadding([rangePad, rangePad, rangePad, rangePad]); + } + + const pointsMode = + customConfig.drawStyle === GraphDrawStyle.Points || hasHighlightIndex + ? VisibilityMode.Always + : customConfig.showPoints; + + builder.addSeries({ + pxAlign: false, + scaleKey, + theme, + colorMode, + thresholds: config.thresholds, + drawStyle: customConfig.drawStyle!, + lineColor: customConfig.lineColor ?? seriesColor, + lineWidth: customConfig.lineWidth, + lineInterpolation: customConfig.lineInterpolation, + showPoints: pointsMode, + pointSize: hasHighlightIndex ? HIGHLIGHT_IDX_POINT_SIZE : customConfig.pointSize, + pointsFilter: hasHighlightIndex ? [sparkline.highlightIndex!] : undefined, + fillOpacity: customConfig.fillOpacity, + fillColor: customConfig.fillColor, + lineStyle: customConfig.lineStyle, + gradientMode: customConfig.gradientMode, + spanNulls: customConfig.spanNulls, + }); + } + + return builder; +}; diff --git a/packages/grafana-ui/src/components/Table/CellActions.tsx b/packages/grafana-ui/src/components/Table/CellActions.tsx index e2fe8a658ba..f21be659c4f 100644 --- a/packages/grafana-ui/src/components/Table/CellActions.tsx +++ b/packages/grafana-ui/src/components/Table/CellActions.tsx @@ -1,3 +1,4 @@ +import { isPlainObject } from 'lodash'; import { useCallback } from 'react'; import * as React from 'react'; @@ -63,7 +64,18 @@ export function CellActions({ tooltip={t('grafana-ui.table.cell-inspect', 'Inspect value')} onClick={() => { if (setInspectCell) { - setInspectCell({ value: cell.value, mode: previewMode }); + let mode = TableCellInspectorMode.text; + let inspectValue = cell.value; + try { + const parsed = typeof inspectValue === 'string' ? JSON.parse(inspectValue) : inspectValue; + if (Array.isArray(parsed) || isPlainObject(parsed)) { + inspectValue = JSON.stringify(parsed, null, 2); + mode = TableCellInspectorMode.code; + } + } catch { + // do nothing + } + setInspectCell({ value: inspectValue, mode }); } }} {...commonButtonProps} diff --git a/packages/grafana-ui/src/components/Table/Table.story.tsx b/packages/grafana-ui/src/components/Table/Table.story.tsx index b6c97df317e..e3d5e4b56cc 100644 --- a/packages/grafana-ui/src/components/Table/Table.story.tsx +++ b/packages/grafana-ui/src/components/Table/Table.story.tsx @@ -263,7 +263,16 @@ export const Footer: StoryFn = (args) => { ); }; -export const Pagination: StoryFn = (args) => ; +export const Pagination: StoryFn = (args) => { + const theme = useTheme2(); + const data = buildData(theme, {}); + + return ( + + + + ); +}; Pagination.args = { enablePagination: true, }; diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx index 56e38b9cd60..ead8014e550 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.test.tsx @@ -451,6 +451,19 @@ describe('TableNG', () => { expect(screen.getByText('A1')).toBeInTheDocument(); expect(screen.getByText('1')).toBeInTheDocument(); }); + + it('shows full column name in title attribute for truncated headers', () => { + const { container } = render( + + ); + + const headers = container.querySelectorAll('[role="columnheader"]'); + const firstHeaderSpan = headers[0].querySelector('span'); + const secondHeaderSpan = headers[1].querySelector('span'); + + expect(firstHeaderSpan).toHaveAttribute('title', 'Column A'); + expect(secondHeaderSpan).toHaveAttribute('title', 'Column B'); + }); }); describe('Footer options', () => { diff --git a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx index 798ca4e1ae0..f17a62b92cf 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/TableNG.tsx @@ -105,6 +105,7 @@ export function TableNG(props: TableNGProps) { const { cellHeight, data, + disableKeyboardEvents, disableSanitizeHtml, enablePagination = false, enableSharedCrosshair = false, @@ -153,8 +154,18 @@ export function TableNG(props: TableNGProps) { const resizeHandler = useColumnResize(onColumnResize); - const rows = useMemo(() => frameToRecords(data), [data]); const hasNestedFrames = useMemo(() => getIsNestedTable(data.fields), [data]); + const nestedFramesFieldName = useMemo(() => { + if (!hasNestedFrames) { + return; + } + const firstNestedField = data.fields.find((f) => f.type === FieldType.nestedFrames); + if (!firstNestedField) { + return; + } + return getDisplayName(firstNestedField); + }, [data, hasNestedFrames]); + const rows = useMemo(() => frameToRecords(data, nestedFramesFieldName), [data, nestedFramesFieldName]); const getTextColorForBackground = useMemo(() => memoize(_getTextColorForBackground, { maxSize: 1000 }), []); const { @@ -373,7 +384,11 @@ export function TableNG(props: TableNGProps) { return null; } - const expandedRecords = applySort(frameToRecords(nestedData), nestedData.fields, sortColumns); + const expandedRecords = applySort( + frameToRecords(nestedData, nestedFramesFieldName), + nestedData.fields, + sortColumns + ); if (!expandedRecords.length) { return (
@@ -397,7 +412,7 @@ export function TableNG(props: TableNGProps) { width: COLUMN.EXPANDER_WIDTH, minWidth: COLUMN.EXPANDER_WIDTH, }), - [commonDataGridProps, data.fields.length, expandedRows, sortColumns, styles] + [commonDataGridProps, data.fields.length, expandedRows, sortColumns, styles, nestedFramesFieldName] ); const fromFields = useCallback( @@ -819,9 +834,9 @@ export function TableNG(props: TableNGProps) { } }} onCellKeyDown={ - hasNestedFrames + hasNestedFrames || disableKeyboardEvents ? (_, event) => { - if (event.isDefaultPrevented()) { + if (disableKeyboardEvents || event.isDefaultPrevented()) { // skip parent grid keyboard navigation if nested grid handled it event.preventGridDefault(); } diff --git a/packages/grafana-ui/src/components/Table/TableNG/components/HeaderCell.tsx b/packages/grafana-ui/src/components/Table/TableNG/components/HeaderCell.tsx index 8ccc73a98b9..fc59c08aa3c 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/components/HeaderCell.tsx +++ b/packages/grafana-ui/src/components/Table/TableNG/components/HeaderCell.tsx @@ -55,7 +55,9 @@ const HeaderCell: React.FC = ({ {showTypeIcons && ( )} - {getDisplayName(field)} + + {displayName} + {direction && ( +
diff --git a/packages/grafana-ui/src/components/Table/TableNG/types.ts b/packages/grafana-ui/src/components/Table/TableNG/types.ts index b828dfddbb6..ddfaf189f34 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/types.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/types.ts @@ -79,7 +79,6 @@ export interface TableRow { // Nested table properties data?: DataFrame; - __nestedFrames?: DataFrame[]; __expanded?: boolean; // For row expansion state // Generic typing for column values @@ -138,6 +137,8 @@ export interface BaseTableProps { enableVirtualization?: boolean; // for MarkdownCell, this flag disables sanitization of HTML content. Configured via config.ini. disableSanitizeHtml?: boolean; + // if true, disables all keyboard events in the table. this is used when previewing a table (i.e. suggestions) + disableKeyboardEvents?: boolean; } /* ---------------------------- Table cell props ---------------------------- */ @@ -260,7 +261,7 @@ export type TableCellStyles = (theme: GrafanaTheme2, options: TableCellStyleOpti export type Comparator = (a: TableCellValue, b: TableCellValue) => number; // Type for converting a DataFrame into an array of TableRows -export type FrameToRowsConverter = (frame: DataFrame) => TableRow[]; +export type FrameToRowsConverter = (frame: DataFrame, nestedFramesFieldName?: string) => TableRow[]; // Type for mapping column names to their field types export type ColumnTypes = Record; diff --git a/packages/grafana-ui/src/components/Table/TableNG/utils.ts b/packages/grafana-ui/src/components/Table/TableNG/utils.ts index 0226f8b6463..083e5c2a8d2 100644 --- a/packages/grafana-ui/src/components/Table/TableNG/utils.ts +++ b/packages/grafana-ui/src/components/Table/TableNG/utils.ts @@ -675,10 +675,12 @@ export function applySort( /** * @internal */ -export const frameToRecords = (frame: DataFrame): TableRow[] => { +export const frameToRecords = (frame: DataFrame, nestedFramesFieldName?: string): TableRow[] => { const fnBody = ` const rows = Array(frame.length); const values = frame.fields.map(f => f.values); + const hasNestedFrames = '${nestedFramesFieldName ?? ''}'.length > 0; + let rowCount = 0; for (let i = 0; i < frame.length; i++) { rows[rowCount] = { @@ -686,11 +688,14 @@ export const frameToRecords = (frame: DataFrame): TableRow[] => { __index: i, ${frame.fields.map((field, fieldIdx) => `${JSON.stringify(getDisplayName(field))}: values[${fieldIdx}][i]`).join(',')} }; - rowCount += 1; - if (rows[rowCount-1]['__nestedFrames']){ - const childFrame = rows[rowCount-1]['__nestedFrames']; - rows[rowCount] = {__depth: 1, __index: i, data: childFrame[0]} - rowCount += 1; + rowCount++; + + if (hasNestedFrames) { + const childFrame = rows[rowCount-1][${JSON.stringify(nestedFramesFieldName)}]; + if (childFrame){ + rows[rowCount] = {__depth: 1, __index: i, data: childFrame[0]} + rowCount++; + } } } return rows; @@ -698,8 +703,9 @@ export const frameToRecords = (frame: DataFrame): TableRow[] => { // Creates a function that converts a DataFrame into an array of TableRows // Uses new Function() for performance as it's faster than creating rows using loops - const convert = new Function('frame', fnBody) as FrameToRowsConverter; - return convert(frame); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + const convert = new Function('frame', 'nestedFramesFieldName', fnBody) as FrameToRowsConverter; + return convert(frame, nestedFramesFieldName); }; /* ----------------------------- Data grid comparator ---------------------------- */ @@ -1102,12 +1108,18 @@ export function parseStyleJson(rawValue: unknown): CSSProperties | void { } } -// Safari 26 introduced rendering bugs which require us to disable several features of the table. +// Safari 26.0 introduced rendering bugs which require us to disable several features of the table. +// The bugs were later fixed in Safari 26.2. export const IS_SAFARI_26 = (() => { if (navigator == null) { return false; } const userAgent = navigator.userAgent; - const safariVersionMatch = userAgent.match(/Version\/(\d+)\./); - return safariVersionMatch && parseInt(safariVersionMatch[1], 10) === 26; + const safariVersionMatch = userAgent.match(/Version\/(\d+)\.(\d+)/); + if (!safariVersionMatch) { + return false; + } + const majorVersion = +safariVersionMatch[1]; + const minorVersion = +safariVersionMatch[2]; + return majorVersion === 26 && minorVersion <= 1; })(); diff --git a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx index 1b6e78213da..524556f258b 100644 --- a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx +++ b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx @@ -54,6 +54,7 @@ export const TagsInput = forwardRef( const [newTagName, setNewTagName] = useState(''); const styles = useStyles2(getStyles); const theme = useTheme2(); + const isTagTooLong = newTagName.length > 50; const onNameChange = useCallback((event: React.ChangeEvent) => { setNewTagName(event.target.value); @@ -65,6 +66,9 @@ export const TagsInput = forwardRef( const onAdd = (event?: React.MouseEvent | React.KeyboardEvent) => { event?.preventDefault(); + if (newTagName.length > 50) { + return; + } if (!tags.includes(newTagName)) { onChange(tags.concat(newTagName)); } @@ -94,14 +98,17 @@ export const TagsInput = forwardRef( value={newTagName} onKeyDown={onKeyboardAdd} onBlur={onBlur} - invalid={invalid} + invalid={invalid || isTagTooLong} suffix={ diff --git a/packages/grafana-ui/src/components/Toggletip/Toggletip.mdx b/packages/grafana-ui/src/components/Toggletip/Toggletip.mdx index 53b75f5b5cb..fcfea97a45f 100644 --- a/packages/grafana-ui/src/components/Toggletip/Toggletip.mdx +++ b/packages/grafana-ui/src/components/Toggletip/Toggletip.mdx @@ -75,5 +75,3 @@ return ( ); ``` - - diff --git a/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx b/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx index 1c3cbb57919..a7006fd70eb 100644 --- a/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx +++ b/packages/grafana-ui/src/components/Toggletip/Toggletip.story.tsx @@ -1,6 +1,11 @@ import { Meta, StoryFn } from '@storybook/react'; +import { useState } from 'react'; import { Button } from '../Button/Button'; +import { Drawer } from '../Drawer/Drawer'; +import { Field } from '../Forms/Field'; +import { Input } from '../Input/Input'; +import { Modal } from '../Modal/Modal'; import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; import mdx from '../Toggletip/Toggletip.mdx'; @@ -133,4 +138,86 @@ LongContent.parameters = { }, }; +export const InsideDrawer: StoryFn = () => { + const [isDrawerOpen, setIsDrawerOpen] = useState(false); + + return ( + <> + + {isDrawerOpen && ( + setIsDrawerOpen(false)}> +
+

This demonstrates using Toggletip inside a Drawer.

+ + + + + +
+ } + footer="Focus should work correctly within this Toggletip" + placement="bottom-start" + > + + +
+ + )} + + ); +}; + +InsideDrawer.parameters = { + controls: { + hideNoControlsWarning: true, + exclude: ['title', 'content', 'footer', 'children', 'placement', 'theme', 'closeButton', 'portalRoot'], + }, +}; + +export const InsideModal: StoryFn = () => { + const [isModalOpen, setIsModalOpen] = useState(false); + + return ( + <> + + setIsModalOpen(false)}> +
+

This demonstrates using Toggletip inside a Modal.

+ + + + + + +
+ } + footer="Focus should work correctly within this Toggletip" + placement="bottom-start" + > + + + +
+ + + ); +}; + +InsideDrawer.parameters = { + controls: { + hideNoControlsWarning: true, + exclude: ['title', 'content', 'footer', 'children', 'placement', 'theme', 'closeButton', 'portalRoot'], + }, +}; + export default meta; diff --git a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx index c1f99b0db93..2193103a90f 100644 --- a/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx +++ b/packages/grafana-ui/src/components/ToolbarButton/ToolbarButton.tsx @@ -206,7 +206,7 @@ const getStyles = (theme: GrafanaTheme2) => { background: 'transparent', border: `1px solid transparent`, - '&:hover, &:focus': { + '&:hover': { color: theme.colors.text.primary, background: theme.colors.action.hover, }, diff --git a/packages/grafana-ui/src/components/UsersIndicator/UserIcon.mdx b/packages/grafana-ui/src/components/UsersIndicator/UserIcon.mdx index d9537dfdc1e..77c189e6e79 100644 --- a/packages/grafana-ui/src/components/UsersIndicator/UserIcon.mdx +++ b/packages/grafana-ui/src/components/UsersIndicator/UserIcon.mdx @@ -66,6 +66,6 @@ export interface UserView { avatarUrl?: string; }; /** Datetime string when the user was last active */ - lastActiveAt: DateTimeInput; + lastActiveAt?: DateTimeInput; } ``` diff --git a/packages/grafana-ui/src/components/UsersIndicator/UserIcon.tsx b/packages/grafana-ui/src/components/UsersIndicator/UserIcon.tsx index ca5ff1f665c..945d46b2f79 100644 --- a/packages/grafana-ui/src/components/UsersIndicator/UserIcon.tsx +++ b/packages/grafana-ui/src/components/UsersIndicator/UserIcon.tsx @@ -10,7 +10,7 @@ import { Tooltip } from '../Tooltip/Tooltip'; import { UserView } from './types'; export interface UserIconProps { - /** An object that contains the user's details and 'lastActiveAt' status */ + /** An object that contains the user's details and an optional 'lastActiveAt' status */ userView: UserView; /** A boolean value that determines whether the tooltip should be shown or not */ showTooltip?: boolean; @@ -64,7 +64,8 @@ export const UserIcon = ({ showTooltip = true, }: PropsWithChildren) => { const { user, lastActiveAt } = userView; - const isActive = dateTime(lastActiveAt).diff(dateTime(), 'minutes', true) >= -15; + const hasActive = lastActiveAt !== undefined && lastActiveAt !== null; + const isActive = hasActive && dateTime(lastActiveAt).diff(dateTime(), 'minutes', true) >= -15; const theme = useTheme2(); const styles = useMemo(() => getStyles(theme, isActive), [theme, isActive]); const content = ( @@ -88,18 +89,20 @@ export const UserIcon = ({ const tooltip = (
{user.name}
-
- {isActive ? ( -
- - Active last 15m - - -
- ) : ( - formatViewed(lastActiveAt) - )} -
+ {hasActive && ( +
+ {isActive ? ( +
+ + Active last 15m + + +
+ ) : ( + formatViewed(lastActiveAt) + )} +
+ )}
); diff --git a/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.mdx b/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.mdx index b5d689af8ea..ade04a32c79 100644 --- a/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.mdx +++ b/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.mdx @@ -60,6 +60,6 @@ export interface UserView { avatarUrl?: string; }; /** Datetime string when the user was last active */ - lastActiveAt: DateTimeInput; + lastActiveAt?: DateTimeInput; } ``` diff --git a/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.tsx b/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.tsx index 66c9a0bddca..04718af9493 100644 --- a/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.tsx +++ b/packages/grafana-ui/src/components/UsersIndicator/UsersIndicator.tsx @@ -9,7 +9,7 @@ import { UserIcon } from './UserIcon'; import { UserView } from './types'; export interface UsersIndicatorProps { - /** An object that contains the user's details and 'lastActiveAt' status */ + /** An object that contains the user's details and an optional 'lastActiveAt' status */ users: UserView[]; /** A limit of how many user icons to show before collapsing them and showing a number of users instead */ limit?: number; @@ -23,7 +23,7 @@ export interface UsersIndicatorProps { * https://developers.grafana.com/ui/latest/index.html?path=/docs/iconography-usersindicator--docs */ export const UsersIndicator = ({ users, onClick, limit = 4 }: UsersIndicatorProps) => { - const styles = useStyles2(getStyles); + const styles = useStyles2(getStyles, limit); if (!users.length) { return null; } @@ -39,34 +39,41 @@ export const UsersIndicator = ({ users, onClick, limit = 4 }: UsersIndicatorProp className={styles.container} aria-label={t('grafana-ui.users-indicator.container-label', 'Users indicator container')} > + {users.slice(0, limitReached ? limit : limit + 1).map((userView, idx, arr) => ( + + ))} {limitReached && ( - + {tooManyUsers ? // eslint-disable-next-line @grafana/i18n/no-untranslated-strings '...' : `+${extraUsers}`} )} - {users - .slice(0, limitReached ? limit : limit + 1) - .reverse() - .map((userView) => ( - - ))} ); }; -const getStyles = (theme: GrafanaTheme2) => { +const getStyles = (theme: GrafanaTheme2, limit: number) => { return { container: css({ display: 'flex', justifyContent: 'center', - flexDirection: 'row-reverse', marginLeft: theme.spacing(1), + isolation: 'isolate', '& > button': { marginLeft: theme.spacing(-1), // Overlay the elements a bit on top of each other + + // Ensure overlaying user icons are stacked correctly with z-index on each element + ...Object.fromEntries( + Array.from({ length: limit }).map((_, idx) => [ + `&:nth-of-type(${idx + 1})`, + { + zIndex: limit - idx, + }, + ]) + ), }, }), dots: css({ diff --git a/packages/grafana-ui/src/components/UsersIndicator/types.ts b/packages/grafana-ui/src/components/UsersIndicator/types.ts index 1ba9f2d4e5b..641afbf1914 100644 --- a/packages/grafana-ui/src/components/UsersIndicator/types.ts +++ b/packages/grafana-ui/src/components/UsersIndicator/types.ts @@ -8,5 +8,5 @@ export interface UserView { avatarUrl?: string; }; /** Datetime string when the user was last active */ - lastActiveAt: DateTimeInput; + lastActiveAt?: DateTimeInput; } diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx index cba6f984501..b9af4d23fc4 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegend.story.tsx @@ -16,10 +16,6 @@ const meta: Meta = { containerWidth: '100%', seriesCount: 5, }, - parameters: { - // TODO fix a11y issue in story and remove this - a11y: { test: 'off' }, - }, argTypes: { containerWidth: { control: { diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendTable.test.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendTable.test.tsx new file mode 100644 index 00000000000..131133bcdfb --- /dev/null +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendTable.test.tsx @@ -0,0 +1,78 @@ +import { render, screen } from '@testing-library/react'; + +import { VizLegendTable } from './VizLegendTable'; +import { VizLegendItem } from './types'; + +describe('VizLegendTable', () => { + const mockItems: VizLegendItem[] = [ + { label: 'Series 1', color: 'red', yAxis: 1 }, + { label: 'Series 2', color: 'blue', yAxis: 1 }, + { label: 'Series 3', color: 'green', yAxis: 1 }, + ]; + + it('renders without crashing', () => { + const { container } = render(); + expect(container.querySelector('table')).toBeInTheDocument(); + }); + + it('renders all items', () => { + render(); + expect(screen.getByText('Series 1')).toBeInTheDocument(); + expect(screen.getByText('Series 2')).toBeInTheDocument(); + expect(screen.getByText('Series 3')).toBeInTheDocument(); + }); + + it('renders table headers when items have display values', () => { + const itemsWithStats: VizLegendItem[] = [ + { + label: 'Series 1', + color: 'red', + yAxis: 1, + getDisplayValues: () => [ + { numeric: 100, text: '100', title: 'Max' }, + { numeric: 50, text: '50', title: 'Min' }, + ], + }, + ]; + render(); + expect(screen.getByText('Max')).toBeInTheDocument(); + expect(screen.getByText('Min')).toBeInTheDocument(); + }); + + it('renders sort icon when sorted', () => { + const { container } = render( + + ); + expect(container.querySelector('svg')).toBeInTheDocument(); + }); + + it('calls onToggleSort when header is clicked', () => { + const onToggleSort = jest.fn(); + render(); + const header = screen.getByText('Name'); + header.click(); + expect(onToggleSort).toHaveBeenCalledWith('Name'); + }); + + it('does not call onToggleSort when not sortable', () => { + const onToggleSort = jest.fn(); + render(); + const header = screen.getByText('Name'); + header.click(); + expect(onToggleSort).not.toHaveBeenCalled(); + }); + + it('renders with long labels', () => { + const itemsWithLongLabels: VizLegendItem[] = [ + { + label: 'This is a very long series name that should be scrollable within its table cell', + color: 'red', + yAxis: 1, + }, + ]; + render(); + expect( + screen.getByText('This is a very long series name that should be scrollable within its table cell') + ).toBeInTheDocument(); + }); +}); diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx index b0f578fae79..b654a2d3ac6 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendTable.tsx @@ -29,11 +29,9 @@ export const VizLegendTable = ({ isSortable, }: VizLegendTableProps): JSX.Element => { const styles = useStyles2(getStyles); - const header: Record = {}; - - if (isSortable) { - header[nameSortKey] = ''; - } + const header: Record = { + [nameSortKey]: '', + }; for (const item of items) { if (item.getDisplayValues) { @@ -90,16 +88,18 @@ export const VizLegendTable = ({
- {!isSortable && } {Object.keys(header).map((columnTitle) => ( - {item.getDisplayValues && @@ -128,6 +130,28 @@ const getStyles = (theme: GrafanaTheme2) => { background: rowHoverBg, }, }), + labelCell: css({ + label: 'LegendLabelCell', + maxWidth: 0, + width: '100%', + minWidth: theme.spacing(16), + }), + labelCellInner: css({ + label: 'LegendLabelCellInner', + display: 'block', + flex: 1, + minWidth: 0, + overflowX: 'auto', + overflowY: 'hidden', + paddingRight: theme.spacing(3), + scrollbarWidth: 'none', + msOverflowStyle: 'none', + maskImage: `linear-gradient(to right, black calc(100% - ${theme.spacing(3)}), transparent 100%)`, + WebkitMaskImage: `linear-gradient(to right, black calc(100% - ${theme.spacing(3)}), transparent 100%)`, + '&::-webkit-scrollbar': { + display: 'none', + }, + }), label: css({ label: 'LegendLabel', whiteSpace: 'nowrap', @@ -135,9 +159,6 @@ const getStyles = (theme: GrafanaTheme2) => { border: 'none', fontSize: 'inherit', padding: 0, - maxWidth: '600px', - textOverflow: 'ellipsis', - overflow: 'hidden', userSelect: 'text', }), labelDisabled: css({ diff --git a/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx b/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx index a1fb6c6a1c3..735e198f0bc 100644 --- a/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx +++ b/packages/grafana-ui/src/components/VizRepeater/VizRepeater.tsx @@ -167,7 +167,8 @@ export class VizRepeater extends PureComponent { expect(screen.queryByRole('button', { name: /filter for 'testValue'/i })).not.toBeInTheDocument(); }); + + it('should render filter by grouping buttons and fire onclick', async () => { + const onForClick = jest.fn(); + const onOutClick = jest.fn(); + + const filterByGroupedLabels = { + onFilterForGroupedLabels: onForClick, + onFilterOutGroupedLabels: onOutClick, + }; + + render( + + + + ); + + const onForButton = screen.getByRole('button', { name: /Apply as filter/i }); + expect(onForButton).toBeInTheDocument(); + + const onOutButton = screen.getByRole('button', { name: /Apply as inverse filter/i }); + expect(onOutButton).toBeInTheDocument(); + + await userEvent.click(onForButton); + expect(onForClick).toHaveBeenCalled(); + + await userEvent.click(onOutButton); + expect(onOutClick).toHaveBeenCalled(); + }); + + it('should not render filter by grouping buttons when there are one-click links', () => { + const filterByGroupedLabels = { + onFilterForGroupedLabels: jest.fn(), + onFilterOutGroupedLabels: jest.fn(), + }; + + const onClick = jest.fn(); + const field: Field = { + name: '', + type: FieldType.string, + values: [], + config: {}, + }; + + const oneClickLink: LinkModel = { + href: '#', + onClick, + title: 'One Click Link', + origin: field, + target: undefined, + oneClick: true, + }; + + render( + + + + ); + + expect(screen.queryByTestId(selectors.components.VizTooltipFooter.buttons.apply)).not.toBeInTheDocument(); + expect(screen.queryByTestId(selectors.components.VizTooltipFooter.buttons.applyInverse)).not.toBeInTheDocument(); + }); }); diff --git a/packages/grafana-ui/src/components/VizTooltip/VizTooltipFooter.tsx b/packages/grafana-ui/src/components/VizTooltip/VizTooltipFooter.tsx index b4eccaee66a..2bd324129f2 100644 --- a/packages/grafana-ui/src/components/VizTooltip/VizTooltipFooter.tsx +++ b/packages/grafana-ui/src/components/VizTooltip/VizTooltipFooter.tsx @@ -2,6 +2,7 @@ import { css } from '@emotion/css'; import { useMemo } from 'react'; import { ActionModel, Field, GrafanaTheme2, LinkModel, ThemeSpacingTokens } from '@grafana/data'; +import { selectors } from '@grafana/e2e-selectors'; import { Trans } from '@grafana/i18n'; import { useStyles2 } from '../../themes/ThemeContext'; @@ -17,10 +18,16 @@ export interface AdHocFilterModel extends AdHocFilterItem { onClick: () => void; } +export interface FilterByGroupedLabelsModel { + onFilterForGroupedLabels?: () => void; + onFilterOutGroupedLabels?: () => void; +} + interface VizTooltipFooterProps { dataLinks: Array>; actions?: Array>; adHocFilters?: AdHocFilterModel[]; + filterByGroupedLabels?: FilterByGroupedLabelsModel; annotate?: () => void; } @@ -85,7 +92,13 @@ const renderActions = makeRenderLinksOrActions( (item, i) => ); -export const VizTooltipFooter = ({ dataLinks, actions = [], annotate, adHocFilters = [] }: VizTooltipFooterProps) => { +export const VizTooltipFooter = ({ + dataLinks, + actions = [], + annotate, + adHocFilters = [], + filterByGroupedLabels, +}: VizTooltipFooterProps) => { const styles = useStyles2(getStyles); const hasOneClickLink = useMemo(() => dataLinks.some((link) => link.oneClick === true), [dataLinks]); const hasOneClickAction = useMemo(() => actions.some((action) => action.oneClick === true), [actions]); @@ -105,6 +118,39 @@ export const VizTooltipFooter = ({ dataLinks, actions = [], annotate, adHocFilte ))} )} + + {!hasOneClickLink && !hasOneClickAction && filterByGroupedLabels && ( +
+ + + + +
+ )} {!hasOneClickLink && !hasOneClickAction && annotate != null && (
- - )} - - ); -} -interface ItemProps { - entry: HistoryEntry; - isSelected: boolean; - onClick: () => void; -} - -function HistoryEntryAppView({ entry, isSelected, onClick }: ItemProps) { - const styles = useStyles2(getStyles); - const theme = useTheme2(); - const [isExpanded, setIsExpanded] = useState(isSelected && entry.views.length > 0); - - const { breadcrumbs, views, time, url, sparklineData } = entry; - const expandedLabel = isExpanded - ? t('nav.history-wrapper.collapse', 'Collapse') - : t('nav.history-wrapper.expand', 'Expand'); - const entryIconLabel = isExpanded - ? t('nav.history-wrapper.icon-selected', 'Selected Entry') - : t('nav.history-wrapper.icon-unselected', 'Normal Entry'); - const selectedViewTime = - isSelected && - entry.views.find((entry) => { - return entry.url === window.location.href; - })?.time; - - return ( - - - - {views.length > 0 ? ( - setIsExpanded(!isExpanded)} - aria-label={expandedLabel} - className={styles.iconButton} - /> - ) : ( - - )} - - { - store.setObject('CLICKING_HISTORY', true); - onClick(); - logClickUnifiedHistoryEntryEvent({ entryURL: url }); - }} - href={url} - isCompact={true} - className={isSelected ? styles.card : cx(styles.card, styles.cardSelected)} - > - -
- {breadcrumbs.map((breadcrumb, index) => ( - - {breadcrumb.text}{' '} - {index !== breadcrumbs.length - 1 - ? // eslint-disable-next-line @grafana/i18n/no-untranslated-strings - '> ' - : ''} - - ))} -
- - {formatDate(time, { timeStyle: 'short' })} - - {sparklineData && ( - - )} -
-
-
- {isExpanded && ( -
- {views.map((view, index) => { - return ( - { - store.setObject('CLICKING_HISTORY', true); - onClick(); - logClickUnifiedHistoryEntryEvent({ entryURL: view.url, subEntry: 'timeRange' }); - }} - isCompact={true} - className={view.time === selectedViewTime ? undefined : styles.subCard} - > - - {view.name} - {view.description && ( - - {view.description} - - )} - - - ); - })} -
- )} -
-
- ); -} -const getStyles = (theme: GrafanaTheme2) => { - return { - card: css({ - label: 'card', - background: 'none', - margin: theme.spacing(0.5, 0), - }), - cardSelected: css({ - label: 'card-selected', - background: 'none', - }), - subCard: css({ - label: 'subcard', - background: 'none', - margin: 0, - }), - iconButton: css({ - label: 'expand-button', - margin: 0, - }), - iconButtonCircle: css({ - label: 'blue-circle-icon', - margin: 0, - background: theme.colors.background.primary, - fill: theme.colors.primary.main, - cursor: 'default', - '&:hover:before': { - background: 'none', - }, - //Need this to place the icon on the line, otherwise the line will appear on top of the icon - zIndex: 0, - }), - iconButtonDot: css({ - label: 'blue-dot-icon', - margin: 0, - color: theme.colors.primary.main, - border: theme.shape.radius.circle, - cursor: 'default', - '&:hover:before': { - background: 'none', - }, - //Need this to place the icon on the line, otherwise the line will appear on top of the icon - zIndex: 0, - }), - expanded: css({ - label: 'expanded', - display: 'flex', - flexDirection: 'column', - marginLeft: theme.spacing(6), - gap: theme.spacing(1), - position: 'relative', - '&:before': { - content: '""', - position: 'absolute', - left: 0, - top: 0, - height: '100%', - width: '1px', - background: theme.colors.border.weak, - }, - }), - timeline: css({ - label: 'timeline', - position: 'relative', - height: '100%', - width: '100%', - paddingLeft: theme.spacing(2), - '&:before': { - content: '""', - position: 'absolute', - left: theme.spacing(5.75), - top: 0, - height: '100%', - width: '1px', - borderLeft: `1px dashed ${theme.colors.border.strong}`, - }, - }), - }; -}; diff --git a/public/app/core/components/AppChrome/History/eventsTracking.ts b/public/app/core/components/AppChrome/History/eventsTracking.ts deleted file mode 100644 index 5d49bd1c978..00000000000 --- a/public/app/core/components/AppChrome/History/eventsTracking.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { reportInteraction } from '@grafana/runtime'; - -const UNIFIED_HISTORY_ENTRY_CLICKED = 'grafana_unified_history_entry_clicked'; -const UNIFIED_HISTORY_ENTRY_DUPLICATED = 'grafana_unified_history_duplicated_entry_rendered'; -const UNIFIED_HISTORY_DRAWER_INTERACTION = 'grafana_unified_history_drawer_interaction'; -const UNIFIED_HISTORY_DRAWER_SHOW_MORE = 'grafana_unified_history_show_more'; - -//Currently just 'timeRange' is supported -//in short term, we could add 'templateVariables' for example -type subEntryTypes = 'timeRange'; - -//Whether the user opens or closes the `HistoryDrawer` -type UnifiedHistoryDrawerInteraction = 'open' | 'close'; - -interface UnifiedHistoryEntryClicked { - //We will also work with the current URL but we will get this from Rudderstack data - //URL to return to - entryURL: string; - //In the case we want to go back to a specific query param, currently just a specific time range - subEntry?: subEntryTypes; -} - -interface UnifiedHistoryEntryDuplicated { - // Common name of the history entries - entryName: string; - // URL of the last entry - lastEntryURL: string; - // URL of the new entry - newEntryURL: string; -} - -//Event triggered when a user clicks on an entry of the `HistoryDrawer` -export const logClickUnifiedHistoryEntryEvent = ({ entryURL, subEntry }: UnifiedHistoryEntryClicked) => { - reportInteraction(UNIFIED_HISTORY_ENTRY_CLICKED, { - entryURL, - subEntry, - }); -}; - -//Event triggered when history entry name matches the previous one -//so we keep track of duplicated entries and be able to analyze them -export const logDuplicateUnifiedHistoryEntryEvent = ({ - entryName, - lastEntryURL, - newEntryURL, -}: UnifiedHistoryEntryDuplicated) => { - reportInteraction(UNIFIED_HISTORY_ENTRY_DUPLICATED, { - entryName, - lastEntryURL, - newEntryURL, - }); -}; - -//We keep track of users open and closing the drawer -export const logUnifiedHistoryDrawerInteractionEvent = ({ type }: { type: UnifiedHistoryDrawerInteraction }) => { - reportInteraction(UNIFIED_HISTORY_DRAWER_INTERACTION, { - type, - }); -}; - -//We keep track of users clicking on the `Show more` button -export const logUnifiedHistoryShowMoreEvent = () => { - reportInteraction(UNIFIED_HISTORY_DRAWER_SHOW_MORE); -}; diff --git a/public/app/core/components/AppChrome/MegaMenu/FeatureHighlight.tsx b/public/app/core/components/AppChrome/MegaMenu/FeatureHighlight.tsx deleted file mode 100644 index ca660e8750c..00000000000 --- a/public/app/core/components/AppChrome/MegaMenu/FeatureHighlight.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { css } from '@emotion/css'; -import type { JSX } from 'react'; - -import { GrafanaTheme2 } from '@grafana/data'; -import { useStyles2 } from '@grafana/ui'; - -export interface Props { - children: JSX.Element; -} - -export const FeatureHighlight = ({ children }: Props): JSX.Element => { - const styles = useStyles2(getStyles); - return ( - <> - {children} - - - ); -}; - -const getStyles = (theme: GrafanaTheme2) => { - return { - highlight: css({ - backgroundColor: theme.colors.success.main, - borderRadius: theme.shape.radius.circle, - width: '6px', - height: '6px', - display: 'inline-block;', - position: 'absolute', - top: '50%', - transform: 'translateY(-50%)', - }), - }; -}; diff --git a/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx b/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx index dead4bd810e..f4ec7598fa2 100644 --- a/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx +++ b/public/app/core/components/AppChrome/MegaMenu/MegaMenu.tsx @@ -62,10 +62,6 @@ export const MegaMenu = memo( const activeItem = getActiveItem(navItems, state.sectionNav.node, location.pathname); - const handleMegaMenu = () => { - chrome.setMegaMenuOpen(!state.megaMenuOpen); - }; - const handleDockedMenu = () => { chrome.setMegaMenuDocked(!state.megaMenuDocked); if (state.megaMenuDocked) { @@ -108,7 +104,7 @@ export const MegaMenu = memo( return (
- +
{ - if (onToggleSort) { + if (onToggleSort && isSortable) { onToggleSort(columnTitle); } }} diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.test.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.test.tsx new file mode 100644 index 00000000000..4ca95aa395c --- /dev/null +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.test.tsx @@ -0,0 +1,112 @@ +import { render, screen } from '@testing-library/react'; + +import { LegendTableItem } from './VizLegendTableItem'; +import { VizLegendItem } from './types'; + +describe('LegendTableItem', () => { + const mockItem: VizLegendItem = { + label: 'Series 1', + color: 'red', + yAxis: 1, + }; + + it('renders without crashing', () => { + const { container } = render( + + + + +
+ ); + expect(container.querySelector('tr')).toBeInTheDocument(); + }); + + it('renders label text', () => { + render( + + + + +
+ ); + expect(screen.getByText('Series 1')).toBeInTheDocument(); + }); + + it('renders with long label text', () => { + const longLabelItem: VizLegendItem = { + ...mockItem, + label: 'This is a very long series name that should be scrollable in the table cell', + }; + render( + + + + +
+ ); + expect( + screen.getByText('This is a very long series name that should be scrollable in the table cell') + ).toBeInTheDocument(); + }); + + it('renders stat values when provided', () => { + const itemWithStats: VizLegendItem = { + ...mockItem, + getDisplayValues: () => [ + { numeric: 100, text: '100', title: 'Max' }, + { numeric: 50, text: '50', title: 'Min' }, + ], + }; + render( + + + + +
+ ); + expect(screen.getByText('100')).toBeInTheDocument(); + expect(screen.getByText('50')).toBeInTheDocument(); + }); + + it('renders right y-axis indicator when yAxis is 2', () => { + const rightAxisItem: VizLegendItem = { + ...mockItem, + yAxis: 2, + }; + render( + + + + +
+ ); + expect(screen.getByText('(right y-axis)')).toBeInTheDocument(); + }); + + it('calls onLabelClick when label is clicked', () => { + const onLabelClick = jest.fn(); + render( + + + + +
+ ); + const button = screen.getByRole('button'); + button.click(); + expect(onLabelClick).toHaveBeenCalledWith(mockItem, expect.any(Object)); + }); + + it('does not call onClick when readonly', () => { + const onLabelClick = jest.fn(); + render( + + + + +
+ ); + const button = screen.getByRole('button'); + expect(button).toBeDisabled(); + }); +}); diff --git a/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx b/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx index 335cf4309e9..6de77fd660b 100644 --- a/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx +++ b/packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx @@ -69,7 +69,7 @@ export const LegendTableItem = ({ return (
+ - +
+ +