Compare commits
16 Commits
viz-change
...
toddtreece
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07bb48e874 | ||
|
|
306186c4ea | ||
|
|
a28c70bbcc | ||
|
|
1ebcd2319a | ||
|
|
5dc3767854 | ||
|
|
040dbfb5e3 | ||
|
|
32d43f5b5d | ||
|
|
fef9c760a0 | ||
|
|
1fe9a38a2a | ||
|
|
59bf7896f4 | ||
|
|
4b4ad544a8 | ||
|
|
7e3289f2c9 | ||
|
|
0d0b5b757b | ||
|
|
c49261cce2 | ||
|
|
d5efce72f3 | ||
|
|
881c81f0b3 |
11
.github/CODEOWNERS
vendored
11
.github/CODEOWNERS
vendored
@@ -208,7 +208,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/oss-big-tent
|
||||
/pkg/tsdb/opentsdb/ @grafana/partner-datasources
|
||||
/pkg/util/ @grafana/grafana-backend-group
|
||||
/pkg/web/ @grafana/grafana-backend-group
|
||||
|
||||
@@ -260,7 +260,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/oss-big-tent
|
||||
/devenv/dev-dashboards/datasource-opentsdb/ @grafana/partner-datasources
|
||||
/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
|
||||
@@ -307,7 +307,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/oss-big-tent
|
||||
/devenv/docker/blocks/opentsdb/ @grafana/partner-datasources
|
||||
/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
|
||||
@@ -520,7 +520,7 @@ i18next.config.ts @grafana/grafana-frontend-platform
|
||||
/e2e-playwright/various-suite/solo-route.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/various-suite/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/dataviz-squad
|
||||
/e2e-playwright/various-suite/visualization-suggestions.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/various-suite/perf-test.spec.ts @grafana/grafana-frontend-platform
|
||||
|
||||
# Packages
|
||||
@@ -956,7 +956,6 @@ 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
|
||||
@@ -1101,7 +1100,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/oss-big-tent
|
||||
/public/app/plugins/datasource/opentsdb/ @grafana/partner-datasources
|
||||
/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
|
||||
|
||||
1
.github/workflows/pr-patch-check-event.yml
vendored
1
.github/workflows/pr-patch-check-event.yml
vendored
@@ -12,7 +12,6 @@ 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.
|
||||
|
||||
21
.github/workflows/pr-patch-check.yml
vendored
21
.github/workflows/pr-patch-check.yml
vendored
@@ -29,10 +29,6 @@ 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 }}
|
||||
@@ -80,20 +76,3 @@ 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"
|
||||
|
||||
13
.github/workflows/release-comms.yml
vendored
13
.github/workflows/release-comms.yml
vendored
@@ -111,13 +111,12 @@ jobs:
|
||||
ownerRepo: 'grafana/grafana-enterprise'
|
||||
from: ${{ needs.setup.outputs.release_branch }}
|
||||
to: ${{ needs.create_next_release_branch_enterprise.outputs.branch }}
|
||||
# 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' }}
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -83,16 +83,6 @@ 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:
|
||||
@@ -291,16 +281,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
|
||||
|
||||
@@ -15,7 +15,6 @@ require (
|
||||
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/kube-openapi v0.0.0-20250910181357-589584f1c912
|
||||
)
|
||||
|
||||
@@ -44,7 +43,6 @@ 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.24.0 // 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
|
||||
@@ -57,7 +55,6 @@ require (
|
||||
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
|
||||
@@ -88,7 +85,6 @@ require (
|
||||
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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
@@ -105,7 +101,6 @@ 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
|
||||
@@ -149,13 +144,12 @@ 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/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-20251212143239-491433b332b7 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba // 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
|
||||
@@ -168,7 +162,6 @@ require (
|
||||
github.com/grafana/sqlds/v4 v4.2.7 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/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
|
||||
@@ -183,7 +176,6 @@ 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
|
||||
@@ -256,9 +248,7 @@ 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.1 // 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
|
||||
@@ -266,9 +256,6 @@ require (
|
||||
github.com/woodsbury/decimal128 v1.3.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.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
|
||||
@@ -287,8 +274,6 @@ require (
|
||||
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
|
||||
@@ -312,26 +297,23 @@ require (
|
||||
google.golang.org/grpc v1.77.0 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.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/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kms v0.34.2 // indirect
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // 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/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.1 // indirect
|
||||
|
||||
@@ -282,7 +282,6 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V
|
||||
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/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=
|
||||
@@ -407,8 +406,6 @@ 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=
|
||||
@@ -609,10 +606,8 @@ 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/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-20251212143239-491433b332b7 h1:ZzG/gCclEit9w0QUfQt9GURcOycAIGcsQAhY1u0AEX0=
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
|
||||
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/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=
|
||||
@@ -754,8 +749,6 @@ 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=
|
||||
@@ -986,7 +979,6 @@ 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=
|
||||
@@ -1004,7 +996,6 @@ 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=
|
||||
@@ -1019,7 +1010,6 @@ github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57J
|
||||
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=
|
||||
@@ -1046,7 +1036,6 @@ 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=
|
||||
@@ -1069,8 +1058,6 @@ 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=
|
||||
@@ -1084,7 +1071,6 @@ 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/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=
|
||||
@@ -1110,7 +1096,6 @@ 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=
|
||||
@@ -1127,8 +1112,6 @@ 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=
|
||||
@@ -1146,8 +1129,6 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY
|
||||
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=
|
||||
@@ -1158,8 +1139,6 @@ 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=
|
||||
@@ -1170,12 +1149,6 @@ go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+
|
||||
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/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=
|
||||
@@ -1328,7 +1301,6 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
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=
|
||||
@@ -1740,7 +1712,6 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251111163417-95abcf5c77ba/go.
|
||||
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.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=
|
||||
|
||||
@@ -8,24 +8,18 @@ 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) {
|
||||
@@ -194,45 +188,3 @@ 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
|
||||
}
|
||||
|
||||
47
apps/advisor/pkg/app/authorizer.go
Normal file
47
apps/advisor/pkg/app/authorizer.go
Normal file
@@ -0,0 +1,47 @@
|
||||
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
|
||||
})
|
||||
}
|
||||
91
apps/advisor/pkg/app/authorizer_test.go
Normal file
91
apps/advisor/pkg/app/authorizer_test.go
Normal file
@@ -0,0 +1,91 @@
|
||||
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
|
||||
@@ -4,7 +4,7 @@ go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7
|
||||
github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba
|
||||
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
|
||||
|
||||
@@ -216,10 +216,12 @@ 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-20251212143239-491433b332b7 h1:ZzG/gCclEit9w0QUfQt9GURcOycAIGcsQAhY1u0AEX0=
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
|
||||
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/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=
|
||||
|
||||
@@ -9,7 +9,6 @@ require (
|
||||
github.com/grafana/grafana-app-sdk/logging v0.48.3
|
||||
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
|
||||
@@ -58,6 +57,7 @@ require (
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-plugin v1.7.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
github.com/jaegertracing/jaeger-idl v0.5.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
|
||||
@@ -1,603 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,715 +0,0 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,7 +530,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -546,7 +546,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -548,7 +548,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -574,7 +574,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -1663,7 +1663,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -1727,7 +1727,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -328,7 +328,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
"kind": "RowsLayoutRow",
|
||||
"spec": {
|
||||
"title": "",
|
||||
"collapse": false,
|
||||
"collapse": true,
|
||||
"hideHeader": true,
|
||||
"layout": {
|
||||
"kind": "GridLayout",
|
||||
|
||||
@@ -1,580 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,783 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,795 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,511 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,683 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -501,9 +501,11 @@ func convertToRowsLayout(ctx context.Context, panels []interface{}, dsIndexProvi
|
||||
|
||||
if currentRow != nil {
|
||||
// If currentRow is a hidden-header row (panels before first explicit row),
|
||||
// it should not be collapsed because it will disappear and be visible only in edit mode
|
||||
// set its collapse to match the first explicit row's collapsed value
|
||||
// This matches frontend behavior: collapse: panel.collapsed
|
||||
if currentRow.Spec.HideHeader != nil && *currentRow.Spec.HideHeader {
|
||||
currentRow.Spec.Collapse = &[]bool{false}[0]
|
||||
rowCollapsed := getBoolField(panelMap, "collapsed", false)
|
||||
currentRow.Spec.Collapse = &rowCollapsed
|
||||
}
|
||||
// Flush current row to layout
|
||||
rows = append(rows, *currentRow)
|
||||
@@ -2020,9 +2022,6 @@ func transformPanelQueries(ctx context.Context, panelMap map[string]interface{},
|
||||
|
||||
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
|
||||
@@ -2519,15 +2518,22 @@ func buildRegexMap(mappingMap map[string]interface{}) *dashv2alpha1.DashboardReg
|
||||
regexMap := &dashv2alpha1.DashboardRegexMap{}
|
||||
regexMap.Type = dashv2alpha1.DashboardMappingTypeRegex
|
||||
|
||||
optMap, ok := mappingMap["options"].(map[string]interface{})
|
||||
opts, ok := mappingMap["options"].([]interface{})
|
||||
if !ok || len(opts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
optMap, ok := opts[0].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
r := dashv2alpha1.DashboardV2alpha1RegexMapOptions{}
|
||||
if pattern, ok := optMap["pattern"].(string); ok {
|
||||
if pattern, ok := optMap["regex"].(string); ok {
|
||||
r.Pattern = pattern
|
||||
}
|
||||
|
||||
// Result is a DashboardValueMappingResult
|
||||
if resMap, ok := optMap["result"].(map[string]interface{}); ok {
|
||||
r.Result = buildValueMappingResult(resMap)
|
||||
}
|
||||
|
||||
@@ -495,9 +495,6 @@ 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 {
|
||||
@@ -505,7 +502,7 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
|
||||
}
|
||||
|
||||
adjustedItem := item
|
||||
adjustedItem.Spec.Y = item.Spec.Y + baseY
|
||||
adjustedItem.Spec.Y = item.Spec.Y + currentY
|
||||
|
||||
panel, err := convertPanelFromElement(&element, &adjustedItem)
|
||||
if err != nil {
|
||||
@@ -514,12 +511,10 @@ func processTabItem(elements map[string]dashv2alpha1.DashboardElement, tab *dash
|
||||
panels = append(panels, panel)
|
||||
|
||||
panelEndY := adjustedItem.Spec.Y + item.Spec.Height
|
||||
if panelEndY > maxY {
|
||||
maxY = panelEndY
|
||||
if panelEndY > currentY {
|
||||
currentY = 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, currentY)
|
||||
|
||||
@@ -5,11 +5,12 @@ import (
|
||||
"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"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/hashicorp/golang-lru/v2/expirable"
|
||||
k8srequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
)
|
||||
|
||||
const defaultCacheSize = 1000
|
||||
@@ -31,15 +32,17 @@ 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
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// 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] {
|
||||
func newCachedProvider[T any](fetch func(context.Context) T, size int, cacheTTL time.Duration, logger log.Logger) *cachedProvider[T] {
|
||||
cacheProvider := &cachedProvider[T]{
|
||||
fetch: fetch,
|
||||
fetch: fetch,
|
||||
logger: logger,
|
||||
}
|
||||
cacheProvider.cache = expirable.NewLRU(size, func(key string, value T) {
|
||||
cacheProvider.inFlight.Delete(key)
|
||||
@@ -50,13 +53,14 @@ func newCachedProvider[T any](fetch func(context.Context) T, size int, cacheTTL
|
||||
// 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 {
|
||||
nsInfo, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
// No namespace, fall back to direct fetch call without caching
|
||||
logging.FromContext(ctx).Warn("Unable to get namespace info from context, skipping cache")
|
||||
p.logger.Warn("Unable to get namespace info from context, skipping cache", "error", err)
|
||||
return p.fetch(ctx)
|
||||
}
|
||||
|
||||
namespace := nsInfo.Value
|
||||
// Fast path: check if cache is still valid
|
||||
if entry, ok := p.cache.Get(namespace); ok {
|
||||
return entry
|
||||
@@ -77,7 +81,7 @@ func (p *cachedProvider[T]) Get(ctx context.Context) T {
|
||||
}
|
||||
|
||||
// Fetch outside the main lock - only this namespace is blocked
|
||||
logging.FromContext(ctx).Debug("cache miss or expired, fetching new value", "namespace", namespace)
|
||||
p.logger.Debug("cache miss or expired, fetching new value", "namespace", namespace)
|
||||
value := p.fetch(ctx)
|
||||
|
||||
// Update the cache for this namespace
|
||||
@@ -89,12 +93,12 @@ func (p *cachedProvider[T]) Get(ctx context.Context) T {
|
||||
// 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))
|
||||
p.logger.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))
|
||||
p.logger.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)))
|
||||
p.cache.Add(nsInfo.Value, p.fetch(k8srequest.WithNamespace(ctx, nsInfo.Value)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
authlib "github.com/grafana/authlib/types"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"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
|
||||
@@ -44,7 +44,7 @@ func TestCachedProvider_CacheHit(t *testing.T) {
|
||||
|
||||
underlying := newTestProvider(datasources)
|
||||
// Test newCachedProvider directly instead of the wrapper
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
// Use "default" namespace (org 1) - this is the standard Grafana namespace format
|
||||
ctx := request.WithNamespace(context.Background(), "default")
|
||||
@@ -69,7 +69,7 @@ func TestCachedProvider_NamespaceIsolation(t *testing.T) {
|
||||
}
|
||||
|
||||
underlying := newTestProvider(datasources)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
// Use "default" (org 1) and "org-2" (org 2) - standard Grafana namespace formats
|
||||
ctx1 := request.WithNamespace(context.Background(), "default")
|
||||
@@ -102,7 +102,7 @@ func TestCachedProvider_NoNamespaceFallback(t *testing.T) {
|
||||
}
|
||||
|
||||
underlying := newTestProvider(datasources)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
// Context without namespace - should fall back to direct provider call
|
||||
ctx := context.Background()
|
||||
@@ -123,7 +123,7 @@ func TestCachedProvider_ConcurrentAccess(t *testing.T) {
|
||||
}
|
||||
|
||||
underlying := newTestProvider(datasources)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
// Use "default" namespace (org 1)
|
||||
ctx := request.WithNamespace(context.Background(), "default")
|
||||
@@ -155,7 +155,7 @@ func TestCachedProvider_ConcurrentNamespaces(t *testing.T) {
|
||||
}
|
||||
|
||||
underlying := newTestProvider(datasources)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
var wg sync.WaitGroup
|
||||
numOrgs := 10
|
||||
@@ -198,7 +198,7 @@ func TestCachedProvider_CorrectDataPerNamespace(t *testing.T) {
|
||||
"org-2": {{UID: "org2-ds", Type: "loki", Name: "Org2 DS", Default: true}},
|
||||
},
|
||||
}
|
||||
cached := newCachedProvider(underlying.Index, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(underlying.Index, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
// Use valid namespace formats
|
||||
ctx1 := request.WithNamespace(context.Background(), "default")
|
||||
@@ -228,7 +228,7 @@ func TestCachedProvider_PreloadMultipleNamespaces(t *testing.T) {
|
||||
"org-3": {{UID: "org3-ds", Type: "tempo", Name: "Org3 DS", Default: true}},
|
||||
},
|
||||
}
|
||||
cached := newCachedProvider(underlying.Index, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(underlying.Index, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
// Preload multiple namespaces
|
||||
nsInfos := []authlib.NamespaceInfo{
|
||||
@@ -346,7 +346,7 @@ func TestCachedProvider_TTLExpiration(t *testing.T) {
|
||||
underlying := newTestProvider(datasources)
|
||||
// Use a very short TTL for testing
|
||||
shortTTL := 50 * time.Millisecond
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, shortTTL)
|
||||
cached := newCachedProvider(underlying.get, defaultCacheSize, shortTTL, log.New("test"))
|
||||
|
||||
ctx := request.WithNamespace(context.Background(), "default")
|
||||
|
||||
@@ -379,7 +379,7 @@ func TestCachedProvider_ParallelNamespacesFetch(t *testing.T) {
|
||||
{UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true},
|
||||
},
|
||||
}
|
||||
cached := newCachedProvider(provider.get, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(provider.get, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
numNamespaces := 5
|
||||
var wg sync.WaitGroup
|
||||
@@ -421,7 +421,7 @@ func TestCachedProvider_SameNamespaceSerialFetch(t *testing.T) {
|
||||
{UID: "ds1", Type: "prometheus", Name: "Prometheus", Default: true},
|
||||
},
|
||||
}
|
||||
cached := newCachedProvider(provider.get, defaultCacheSize, time.Minute)
|
||||
cached := newCachedProvider(provider.get, defaultCacheSize, time.Minute, log.New("test"))
|
||||
|
||||
numGoroutines := 10
|
||||
var wg sync.WaitGroup
|
||||
|
||||
@@ -3,6 +3,8 @@ package schemaversion
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
)
|
||||
|
||||
// Shared utility functions for datasource migrations across different schema versions.
|
||||
@@ -34,7 +36,7 @@ func WrapIndexProviderWithCache(provider DataSourceIndexProvider, cacheTTL time.
|
||||
return provider
|
||||
}
|
||||
return &cachedIndexProvider{
|
||||
newCachedProvider[*DatasourceIndex](provider.Index, defaultCacheSize, cacheTTL),
|
||||
newCachedProvider[*DatasourceIndex](provider.Index, defaultCacheSize, cacheTTL, log.New("schemaversion.dsindexprovider")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +46,7 @@ func WrapLibraryElementProviderWithCache(provider LibraryElementIndexProvider, c
|
||||
return provider
|
||||
}
|
||||
return &cachedLibraryElementProvider{
|
||||
newCachedProvider[[]LibraryElementInfo](provider.GetLibraryElementInfo, defaultCacheSize, cacheTTL),
|
||||
newCachedProvider[[]LibraryElementInfo](provider.GetLibraryElementInfo, defaultCacheSize, cacheTTL, log.New("schemaversion.leindexprovider")),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,9 +75,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -154,9 +154,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -233,9 +233,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -312,9 +312,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -391,9 +391,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -470,9 +470,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": false,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -549,9 +549,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": false,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -641,9 +641,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -720,9 +720,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -799,9 +799,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -878,9 +878,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": false,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -974,9 +974,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1053,9 +1053,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1132,9 +1132,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": true,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": true
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1211,9 +1211,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1290,9 +1290,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1386,9 +1386,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": true,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": true
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1469,9 +1469,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": true,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": true
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1552,9 +1552,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": true,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": true
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1603,6 +1603,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -1643,9 +1644,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": true,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": true
|
||||
},
|
||||
"glow": "both",
|
||||
"orientation": "auto",
|
||||
@@ -1670,6 +1671,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"hide": false,
|
||||
"max": 98,
|
||||
"min": 5,
|
||||
"noise": 22,
|
||||
@@ -1687,6 +1689,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -1727,9 +1730,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": true,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": true
|
||||
},
|
||||
"glow": "both",
|
||||
"orientation": "auto",
|
||||
@@ -1754,6 +1757,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"hide": false,
|
||||
"max": 98,
|
||||
"min": 5,
|
||||
"noise": 22,
|
||||
@@ -1784,6 +1788,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -1825,9 +1830,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": true,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": true
|
||||
},
|
||||
"glow": "both",
|
||||
"orientation": "auto",
|
||||
@@ -1852,6 +1857,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"hide": false,
|
||||
"max": 8,
|
||||
"min": 1,
|
||||
"noise": 2,
|
||||
@@ -1869,6 +1875,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -1910,9 +1917,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": true,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": true
|
||||
},
|
||||
"glow": "both",
|
||||
"orientation": "auto",
|
||||
@@ -1937,6 +1944,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"hide": false,
|
||||
"max": 12,
|
||||
"min": 1,
|
||||
"noise": 2,
|
||||
@@ -1954,6 +1962,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -1994,9 +2003,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": true,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": true
|
||||
},
|
||||
"glow": "both",
|
||||
"orientation": "auto",
|
||||
@@ -2021,6 +2030,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"hide": false,
|
||||
"max": 100,
|
||||
"min": 10,
|
||||
"noise": 22,
|
||||
@@ -2038,6 +2048,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
@@ -2078,9 +2089,9 @@
|
||||
"effects": {
|
||||
"barGlow": true,
|
||||
"centerGlow": true,
|
||||
"gradient": true,
|
||||
"rounded": true,
|
||||
"spotlight": true
|
||||
"spotlight": true,
|
||||
"gradient": true
|
||||
},
|
||||
"glow": "both",
|
||||
"orientation": "auto",
|
||||
@@ -2105,6 +2116,7 @@
|
||||
"datasource": {
|
||||
"type": "grafana-testdata-datasource"
|
||||
},
|
||||
"hide": false,
|
||||
"max": 100,
|
||||
"min": 10,
|
||||
"noise": 22,
|
||||
@@ -2117,151 +2129,6 @@
|
||||
],
|
||||
"title": "Backend",
|
||||
"type": "radialbar"
|
||||
},
|
||||
{
|
||||
"collapsed": false,
|
||||
"gridPos": {
|
||||
"h": 1,
|
||||
"w": 24,
|
||||
"x": 0,
|
||||
"y": 66
|
||||
},
|
||||
"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": 8,
|
||||
"w": 6,
|
||||
"x": 0,
|
||||
"y": 67
|
||||
},
|
||||
"id": 36,
|
||||
"options": {
|
||||
"barWidthFactor": 0.5,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": true,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"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": 8,
|
||||
"w": 6,
|
||||
"x": 6,
|
||||
"y": 67
|
||||
},
|
||||
"id": 37,
|
||||
"options": {
|
||||
"barWidthFactor": 0.5,
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": true,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
},
|
||||
"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,
|
||||
@@ -2279,4 +2146,4 @@
|
||||
"title": "Panel tests - Gauge (new)",
|
||||
"uid": "panel-tests-gauge-new",
|
||||
"weekStart": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -955,9 +955,9 @@
|
||||
"effects": {
|
||||
"barGlow": false,
|
||||
"centerGlow": false,
|
||||
"gradient": false,
|
||||
"rounded": false,
|
||||
"spotlight": false
|
||||
"spotlight": false,
|
||||
"gradient": false
|
||||
},
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
@@ -1162,4 +1162,4 @@
|
||||
"title": "Panel tests - Old gauge to new",
|
||||
"uid": "panel-tests-old-gauge-to-new",
|
||||
"weekStart": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ 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-20251212143239-491433b332b7 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba // 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
|
||||
|
||||
@@ -817,8 +817,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-20251212143239-491433b332b7 h1:ZzG/gCclEit9w0QUfQt9GURcOycAIGcsQAhY1u0AEX0=
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
|
||||
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/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=
|
||||
|
||||
@@ -22,40 +22,13 @@ 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: {
|
||||
@@ -78,15 +51,3 @@ v0alpha1: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#UserHit: {
|
||||
name: string
|
||||
title: string
|
||||
login: string
|
||||
email: string
|
||||
role: string
|
||||
lastSeenAt: int64
|
||||
lastSeenAtAge: string
|
||||
provisioned: bool
|
||||
score: float64
|
||||
}
|
||||
|
||||
@@ -29,9 +29,6 @@ userv0alpha1: userKind & {
|
||||
// }
|
||||
schema: {
|
||||
spec: v0alpha1.UserSpec
|
||||
status: {
|
||||
lastSeenAt: int64 | 0
|
||||
}
|
||||
}
|
||||
// TODO: Uncomment when the custom routes implementation is done
|
||||
// routes: {
|
||||
|
||||
@@ -3,10 +3,7 @@
|
||||
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"`
|
||||
Query *string `json:"query,omitempty"`
|
||||
}
|
||||
|
||||
// NewGetSearchTeamsRequestParams creates a new GetSearchTeamsRequestParams object.
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// 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()
|
||||
@@ -1,15 +0,0 @@
|
||||
// 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{}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// 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{},
|
||||
}
|
||||
}
|
||||
19
apps/iam/pkg/apis/iam/v0alpha1/user_client_gen.go
generated
19
apps/iam/pkg/apis/iam/v0alpha1/user_client_gen.go
generated
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type UserClient struct {
|
||||
@@ -76,24 +75,6 @@ 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)
|
||||
}
|
||||
|
||||
31
apps/iam/pkg/apis/iam/v0alpha1/user_object_gen.go
generated
31
apps/iam/pkg/apis/iam/v0alpha1/user_object_gen.go
generated
@@ -21,14 +21,11 @@ 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(),
|
||||
Spec: *NewUserSpec(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,15 +43,11 @@ func (o *User) SetSpec(spec any) error {
|
||||
}
|
||||
|
||||
func (o *User) GetSubresources() map[string]any {
|
||||
return map[string]any{
|
||||
"status": o.Status,
|
||||
}
|
||||
return map[string]any{}
|
||||
}
|
||||
|
||||
func (o *User) GetSubresource(name string) (any, bool) {
|
||||
switch name {
|
||||
case "status":
|
||||
return o.Status, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
@@ -62,13 +55,6 @@ 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)
|
||||
}
|
||||
@@ -240,7 +226,6 @@ 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
|
||||
@@ -312,15 +297,3 @@ 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)
|
||||
}
|
||||
|
||||
33
apps/iam/pkg/apis/iam/v0alpha1/user_status_gen.go
generated
33
apps/iam/pkg/apis/iam/v0alpha1/user_status_gen.go
generated
@@ -2,12 +2,43 @@
|
||||
|
||||
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 {
|
||||
LastSeenAt int64 `json:"lastSeenAt"`
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// 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"
|
||||
)
|
||||
|
||||
230
apps/iam/pkg/apis/iam/v0alpha1/zz_openapi_gen.go
generated
230
apps/iam/pkg/apis/iam/v0alpha1/zz_openapi_gen.go
generated
@@ -21,7 +21,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
|
||||
"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),
|
||||
@@ -73,10 +72,10 @@ 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),
|
||||
}
|
||||
@@ -689,62 +688,6 @@ func schema_pkg_apis_iam_v0alpha1_GetSearchTeamsBody(ref common.ReferenceCallbac
|
||||
}
|
||||
}
|
||||
|
||||
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{
|
||||
@@ -2890,94 +2833,12 @@ 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", "status"},
|
||||
Required: []string{"metadata", "spec"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"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"},
|
||||
},
|
||||
},
|
||||
"github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1.UserSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3104,15 +2965,90 @@ func schema_pkg_apis_iam_v0alpha1_UserStatus(ref common.ReferenceCallback) commo
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"lastSeenAt": {
|
||||
"operatorStates": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
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: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"lastSeenAt"},
|
||||
},
|
||||
},
|
||||
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"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
206
apps/iam/pkg/apis/iam_manifest.go
generated
206
apps/iam/pkg/apis/iam_manifest.go
generated
@@ -173,36 +173,6 @@ var appManifestData = app.ManifestData{
|
||||
|
||||
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",
|
||||
@@ -291,118 +261,6 @@ var appManifestData = app.ManifestData{
|
||||
},
|
||||
},
|
||||
},
|
||||
"/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{
|
||||
@@ -445,69 +303,6 @@ var appManifestData = app.ManifestData{
|
||||
},
|
||||
},
|
||||
},
|
||||
"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",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -547,7 +342,6 @@ var customRouteToGoResponseType = map[string]any{
|
||||
"v0alpha1|Team|groups|GET": v0alpha1.GetGroups{},
|
||||
|
||||
"v0alpha1||<namespace>/searchTeams|GET": v0alpha1.GetSearchTeams{},
|
||||
"v0alpha1||<namespace>/searchUsers|GET": v0alpha1.GetSearchUsers{},
|
||||
}
|
||||
|
||||
// ManifestCustomRouteResponsesAssociator returns the associated response go type for a given kind, version, custom route path, and method, if one exists.
|
||||
|
||||
@@ -24,6 +24,7 @@ require (
|
||||
require (
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.6 // 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
|
||||
@@ -35,16 +36,21 @@ require (
|
||||
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/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/bluele/gcache v0.0.2 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // 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/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
|
||||
@@ -74,7 +80,7 @@ require (
|
||||
github.com/google/gnostic-models v0.7.0 // 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-20251212143239-491433b332b7 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20251204145817-de8c2bbf9eba // 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
|
||||
@@ -132,11 +138,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
|
||||
@@ -155,6 +165,7 @@ require (
|
||||
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/x448/float16 v0.8.4 // indirect
|
||||
@@ -176,6 +187,8 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.38.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
|
||||
|
||||
@@ -4,9 +4,13 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
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/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.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
|
||||
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
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=
|
||||
@@ -38,12 +42,18 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.38.5 h1:+LVB0xBqEgjQoqr9bGZbRzvg212B
|
||||
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/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/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-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
@@ -60,6 +70,8 @@ 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=
|
||||
@@ -69,6 +81,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
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=
|
||||
@@ -174,8 +188,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-20251212143239-491433b332b7 h1:ZzG/gCclEit9w0QUfQt9GURcOycAIGcsQAhY1u0AEX0=
|
||||
github.com/grafana/alerting v0.0.0-20251212143239-491433b332b7/go.mod h1:l7v67cgP7x72ajB9UPZlumdrHqNztpKoqQ52cU8T3LU=
|
||||
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/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=
|
||||
@@ -341,6 +355,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 +371,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=
|
||||
@@ -440,6 +462,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=
|
||||
@@ -507,8 +533,12 @@ go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJr
|
||||
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/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=
|
||||
|
||||
@@ -5,7 +5,24 @@ metaV0Alpha1: {
|
||||
scope: "Namespaced"
|
||||
schema: {
|
||||
spec: {
|
||||
pluginJSON: #JSONData,
|
||||
pluginJson: #JSONData
|
||||
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]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,13 +208,20 @@ func NewMetaExtensions() *MetaExtensions {
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type MetaSpec struct {
|
||||
PluginJSON MetaJSONData `json:"pluginJSON"`
|
||||
PluginJson MetaJSONData `json:"pluginJson"`
|
||||
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(),
|
||||
PluginJson: *NewMetaJSONData(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,6 +419,40 @@ func NewMetaV0alpha1ExtensionsExtensionPoints() *MetaV0alpha1ExtensionsExtension
|
||||
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
|
||||
|
||||
@@ -472,3 +513,33 @@ const (
|
||||
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"
|
||||
)
|
||||
|
||||
2
apps/plugins/pkg/apis/plugins_manifest.go
generated
2
apps/plugins/pkg/apis/plugins_manifest.go
generated
File diff suppressed because one or more lines are too long
@@ -10,8 +10,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
|
||||
pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -87,45 +85,9 @@ func (p *CatalogProvider) GetMeta(ctx context.Context, pluginID, version string)
|
||||
return nil, fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
|
||||
metaSpec := grafanaComPluginVersionMetaToMetaSpec(gcomMeta)
|
||||
return &Result{
|
||||
Meta: gcomMeta.JSON,
|
||||
Meta: metaSpec,
|
||||
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.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"`
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func TestCatalogProvider_GetMeta(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result)
|
||||
assert.Equal(t, expectedMeta, result.Meta)
|
||||
assert.Equal(t, expectedMeta, result.Meta.PluginJson)
|
||||
assert.Equal(t, defaultCatalogTTL, result.TTL)
|
||||
})
|
||||
|
||||
|
||||
725
apps/plugins/pkg/app/meta/converter.go
Normal file
725
apps/plugins/pkg/app/meta/converter.go
Normal file
@@ -0,0 +1,725 @@
|
||||
package meta
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1"
|
||||
"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 "Admin":
|
||||
role = pluginsv0alpha1.MetaIncludeRoleAdmin
|
||||
case "Editor":
|
||||
role = pluginsv0alpha1.MetaIncludeRoleEditor
|
||||
case "Viewer":
|
||||
role = pluginsv0alpha1.MetaIncludeRoleViewer
|
||||
}
|
||||
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 {
|
||||
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.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),
|
||||
}
|
||||
|
||||
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 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,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -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/services/pluginsintegration/pluginerrs"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,9 +30,10 @@ const (
|
||||
// CoreProvider retrieves plugin metadata for core plugins.
|
||||
type CoreProvider struct {
|
||||
mu sync.RWMutex
|
||||
loadedPlugins map[string]pluginsv0alpha1.MetaJSONData
|
||||
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.MetaJSONData),
|
||||
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 := jsonDataToMetaJSONData(bundle.Primary.JSONData)
|
||||
p.loadedPlugins[bundle.Primary.JSONData.ID] = meta
|
||||
for _, plugin := range loadedPlugins {
|
||||
metaSpec := pluginToMetaSpec(plugin)
|
||||
p.loadedPlugins[plugin.ID] = metaSpec
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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,
|
||||
// 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.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 "Admin":
|
||||
role = pluginsv0alpha1.MetaIncludeRoleAdmin
|
||||
case "Editor":
|
||||
role = pluginsv0alpha1.MetaIncludeRoleEditor
|
||||
case "Viewer":
|
||||
role = pluginsv0alpha1.MetaIncludeRoleViewer
|
||||
}
|
||||
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 {
|
||||
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.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
|
||||
return pluginsLoader.New(cfg, d, b, v, i, t, et)
|
||||
}
|
||||
|
||||
@@ -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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
53
apps/plugins/pkg/app/meta/local.go
Normal file
53
apps/plugins/pkg/app/meta/local.go
Normal file
@@ -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
|
||||
}
|
||||
@@ -16,7 +16,7 @@ const (
|
||||
|
||||
// cachedMeta represents a cached metadata entry with expiration time
|
||||
type cachedMeta struct {
|
||||
meta pluginsv0alpha1.MetaJSONData
|
||||
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()
|
||||
|
||||
@@ -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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Zero TTL Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
}
|
||||
expectedMeta := pluginsv0alpha1.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Expired Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
expiredMeta := pluginsv0alpha1.MetaSpec{
|
||||
PluginJson: pluginsv0alpha1.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Expired Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
},
|
||||
}
|
||||
expectedMeta := pluginsv0alpha1.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Provider 1 Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
expectedMeta1 := pluginsv0alpha1.MetaSpec{
|
||||
PluginJson: pluginsv0alpha1.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Provider 1 Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
},
|
||||
}
|
||||
expectedMeta2 := pluginsv0alpha1.MetaJSONData{
|
||||
Id: "test-plugin",
|
||||
Name: "Provider 2 Plugin",
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
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.MetaJSONData{Id: "valid"}
|
||||
expiredMeta1 := pluginsv0alpha1.MetaJSONData{Id: "expired1"}
|
||||
expiredMeta2 := pluginsv0alpha1.MetaJSONData{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) {
|
||||
|
||||
@@ -14,7 +14,7 @@ var (
|
||||
|
||||
// Result contains plugin metadata along with its recommended TTL.
|
||||
type Result struct {
|
||||
Meta pluginsv0alpha1.MetaJSONData
|
||||
Meta pluginsv0alpha1.MetaSpec
|
||||
TTL time.Duration
|
||||
}
|
||||
|
||||
|
||||
@@ -121,8 +121,19 @@ func (s *MetaStorage) List(ctx context.Context, options *internalversion.ListOpt
|
||||
continue
|
||||
}
|
||||
|
||||
pluginMeta := createMetaFromMetaJSONData(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.MetaList{
|
||||
@@ -169,27 +180,18 @@ func (s *MetaStorage) Get(ctx context.Context, name string, options *metav1.GetO
|
||||
return nil, apierrors.NewInternalError(fmt.Errorf("failed to fetch plugin metadata: %w", err))
|
||||
}
|
||||
|
||||
return createMetaFromMetaJSONData(result.Meta, name, ns.Value), nil
|
||||
}
|
||||
|
||||
// createMetaFromMetaJSONData creates a Meta k8s object from MetaJSONData and plugin metadata.
|
||||
func createMetaFromMetaJSONData(pluginJSON pluginsv0alpha1.MetaJSONData, name, namespace string) *pluginsv0alpha1.Meta {
|
||||
pluginMeta := &pluginsv0alpha1.Meta{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Spec: pluginsv0alpha1.MetaSpec{
|
||||
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.MetaKind().Kind(),
|
||||
})
|
||||
|
||||
return pluginMeta
|
||||
return pluginMeta, nil
|
||||
}
|
||||
|
||||
249
apps/plugins/pkg/app/storage_test.go
Normal file
249
apps/plugins/pkg/app/storage_test.go
Normal file
@@ -0,0 +1,249 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
|
||||
pluginsv0alpha1 "github.com/grafana/grafana/apps/plugins/pkg/apis/plugins/v0alpha1"
|
||||
"github.com/grafana/grafana/apps/plugins/pkg/app/meta"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
)
|
||||
|
||||
func TestMetaStorageListPreload(t *testing.T) {
|
||||
ctx := request.WithNamespace(context.Background(), "default")
|
||||
|
||||
preloadPlugin := pluginstore.Plugin{
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "test-plugin",
|
||||
Name: "Test Plugin",
|
||||
Type: plugins.TypeDataSource,
|
||||
Info: plugins.Info{Version: "1.0.0"},
|
||||
Preload: true,
|
||||
},
|
||||
}
|
||||
nonPreloadPlugin := pluginstore.Plugin{
|
||||
JSONData: plugins.JSONData{
|
||||
ID: "test-plugin-2",
|
||||
Name: "Test Plugin 2",
|
||||
Type: plugins.TypeDataSource,
|
||||
Info: plugins.Info{Version: "1.0.0"},
|
||||
Preload: false,
|
||||
},
|
||||
}
|
||||
|
||||
store := &mockPluginStore{plugins: map[string]pluginstore.Plugin{
|
||||
"test-plugin": preloadPlugin,
|
||||
}}
|
||||
store2 := &mockPluginStore{plugins: map[string]pluginstore.Plugin{
|
||||
"test-plugin-2": nonPreloadPlugin,
|
||||
}}
|
||||
catalogServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
require.Equal(t, http.MethodGet, r.Method)
|
||||
require.Equal(t, "application/json", r.Header.Get("Accept"))
|
||||
require.Equal(t, "grafana-plugins-app", r.Header.Get("User-Agent"))
|
||||
|
||||
segments := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
|
||||
require.Len(t, segments, 5)
|
||||
require.Equal(t, "api", segments[0])
|
||||
require.Equal(t, "plugins", segments[1])
|
||||
require.Equal(t, "versions", segments[3])
|
||||
|
||||
preload := true
|
||||
response := struct {
|
||||
PluginID string `json:"pluginSlug"`
|
||||
Version string `json:"version"`
|
||||
JSON pluginsv0alpha1.MetaJSONData `json:"json"`
|
||||
}{
|
||||
PluginID: segments[2],
|
||||
Version: segments[4],
|
||||
JSON: pluginsv0alpha1.MetaJSONData{
|
||||
Id: segments[2],
|
||||
Name: segments[2],
|
||||
Type: pluginsv0alpha1.MetaJSONDataTypeDatasource,
|
||||
Preload: &preload,
|
||||
},
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
require.NoError(t, json.NewEncoder(w).Encode(response))
|
||||
}))
|
||||
defer catalogServer.Close()
|
||||
provider := meta.NewLocalProvider(store, mockPluginAssets{})
|
||||
provider2 := meta.NewLocalProvider(store2, mockPluginAssets{})
|
||||
catalogProvider := meta.NewCatalogProvider(catalogServer.URL + "/api/plugins")
|
||||
metaManager := meta.NewProviderManager(provider2, provider, catalogProvider)
|
||||
|
||||
pluginClient := pluginsv0alpha1.NewPluginClient(&mockResourceClient{
|
||||
listFunc: func(ctx context.Context, namespace string, opts resource.ListOptions) (resource.ListObject, error) {
|
||||
return newPluginList(), nil
|
||||
},
|
||||
})
|
||||
|
||||
storage := NewMetaStorage(metaManager, func(ctx context.Context) (*pluginsv0alpha1.PluginClient, error) {
|
||||
return pluginClient, nil
|
||||
})
|
||||
|
||||
obj, err := storage.List(ctx, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
metaList, ok := obj.(*pluginsv0alpha1.MetaList)
|
||||
require.True(t, ok)
|
||||
require.Len(t, metaList.Items, 3)
|
||||
|
||||
require.NotNil(t, metaList.Items[0].Spec.PluginJson.Preload)
|
||||
require.True(t, *metaList.Items[0].Spec.PluginJson.Preload)
|
||||
require.NotNil(t, metaList.Items[1].Spec.PluginJson.Preload)
|
||||
require.True(t, *metaList.Items[1].Spec.PluginJson.Preload)
|
||||
require.Nil(t, metaList.Items[2].Spec.PluginJson.Preload)
|
||||
|
||||
obj, err = storage.List(ctx, nil)
|
||||
require.NoError(t, err)
|
||||
metaList, ok = obj.(*pluginsv0alpha1.MetaList)
|
||||
require.True(t, ok)
|
||||
require.Len(t, metaList.Items, 3)
|
||||
require.NotNil(t, metaList.Items[0].Spec.PluginJson.Preload)
|
||||
require.True(t, *metaList.Items[0].Spec.PluginJson.Preload)
|
||||
require.NotNil(t, metaList.Items[1].Spec.PluginJson.Preload)
|
||||
require.True(t, *metaList.Items[1].Spec.PluginJson.Preload)
|
||||
require.Nil(t, metaList.Items[2].Spec.PluginJson.Preload)
|
||||
}
|
||||
|
||||
type mockPluginAssets struct{}
|
||||
|
||||
func (mockPluginAssets) LoadingStrategy(ctx context.Context, p pluginstore.Plugin) plugins.LoadingStrategy {
|
||||
return plugins.LoadingStrategyFetch
|
||||
}
|
||||
|
||||
func (mockPluginAssets) ModuleHash(ctx context.Context, p pluginstore.Plugin) string {
|
||||
return "hash"
|
||||
}
|
||||
|
||||
type mockPluginStore struct {
|
||||
plugins map[string]pluginstore.Plugin
|
||||
}
|
||||
|
||||
func (m *mockPluginStore) Plugin(ctx context.Context, pluginID string) (pluginstore.Plugin, bool) {
|
||||
if m.plugins[pluginID].ID != pluginID {
|
||||
return pluginstore.Plugin{}, false
|
||||
}
|
||||
return m.plugins[pluginID], true
|
||||
}
|
||||
|
||||
func (m *mockPluginStore) Plugins(ctx context.Context, pluginTypes ...plugins.Type) []pluginstore.Plugin {
|
||||
result := []pluginstore.Plugin{}
|
||||
for _, plugin := range m.plugins {
|
||||
if len(pluginTypes) == 0 || slices.Contains(pluginTypes, plugin.Type) {
|
||||
result = append(result, plugin)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func newPluginList() *pluginsv0alpha1.PluginList {
|
||||
return &pluginsv0alpha1.PluginList{
|
||||
Items: []pluginsv0alpha1.Plugin{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "grafana-plugins-app", Namespace: "org-1"},
|
||||
Spec: pluginsv0alpha1.PluginSpec{Id: "grafana-plugins-app", Version: "1.0.0"},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-plugin", Namespace: "org-1"},
|
||||
Spec: pluginsv0alpha1.PluginSpec{Id: "test-plugin", Version: "1.0.0"},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-plugin-2", Namespace: "org-1"},
|
||||
Spec: pluginsv0alpha1.PluginSpec{Id: "test-plugin-2", Version: "1.0.0"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type mockResourceClient struct {
|
||||
listFunc func(ctx context.Context, namespace string, opts resource.ListOptions) (resource.ListObject, error)
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) List(ctx context.Context, namespace string, opts resource.ListOptions) (resource.ListObject, error) {
|
||||
if m.listFunc != nil {
|
||||
return m.listFunc(ctx, namespace, opts)
|
||||
}
|
||||
return &pluginsv0alpha1.PluginList{}, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) ListInto(ctx context.Context, namespace string, opts resource.ListOptions, into resource.ListObject) error {
|
||||
list, err := m.List(ctx, namespace, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if src, ok := list.(*pluginsv0alpha1.PluginList); ok {
|
||||
if dst, ok := into.(*pluginsv0alpha1.PluginList); ok {
|
||||
*dst = *src
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) Get(ctx context.Context, identifier resource.Identifier) (resource.Object, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) GetInto(ctx context.Context, identifier resource.Identifier, into resource.Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) Create(ctx context.Context, identifier resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) CreateInto(ctx context.Context, identifier resource.Identifier, obj resource.Object, opts resource.CreateOptions, into resource.Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) Update(ctx context.Context, identifier resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) UpdateInto(ctx context.Context, identifier resource.Identifier, obj resource.Object, opts resource.UpdateOptions, into resource.Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) Patch(ctx context.Context, identifier resource.Identifier, patch resource.PatchRequest, opts resource.PatchOptions) (resource.Object, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) PatchInto(ctx context.Context, identifier resource.Identifier, patch resource.PatchRequest, opts resource.PatchOptions, into resource.Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) Delete(ctx context.Context, identifier resource.Identifier, opts resource.DeleteOptions) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) SubresourceRequest(ctx context.Context, identifier resource.Identifier, req resource.CustomRouteRequestOptions) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockResourceClient) Watch(ctx context.Context, namespace string, opts resource.WatchOptions) (resource.WatchResponse, error) {
|
||||
return &mockWatchResponse{}, nil
|
||||
}
|
||||
|
||||
type mockWatchResponse struct{}
|
||||
|
||||
func (m *mockWatchResponse) Stop() {}
|
||||
|
||||
func (m *mockWatchResponse) WatchEvents() <-chan resource.WatchEvent {
|
||||
ch := make(chan resource.WatchEvent)
|
||||
close(ch)
|
||||
return ch
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,5 @@ manifest: {
|
||||
groupOverride: "provisioning.grafana.app"
|
||||
kinds: [
|
||||
repository,
|
||||
connection
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
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:"webhook,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"`
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
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"`
|
||||
}
|
||||
@@ -198,7 +198,6 @@ 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"`
|
||||
@@ -226,20 +225,18 @@ 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
|
||||
Warning int64 `json:"warning,omitempty"` // The warning 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
|
||||
|
||||
// No action required (useful for sync)
|
||||
Noop int64 `json:"noop,omitempty"`
|
||||
|
||||
// Report errors/warnings for this resource type
|
||||
// Report errors 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"`
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
// HistoricJob is an append only log, saving all jobs that have been processed.
|
||||
|
||||
@@ -115,47 +115,6 @@ 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}
|
||||
@@ -195,8 +154,6 @@ func AddKnownTypes(gv schema.GroupVersion, scheme *runtime.Scheme) error {
|
||||
&RefList{},
|
||||
&HistoricJob{},
|
||||
&HistoricJobList{},
|
||||
&Connection{},
|
||||
&ConnectionList{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -315,6 +315,31 @@ 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"`
|
||||
|
||||
@@ -27,22 +27,6 @@ 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
|
||||
@@ -59,135 +43,6 @@ 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 *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
|
||||
@@ -293,22 +148,6 @@ 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
|
||||
@@ -357,22 +196,6 @@ 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
|
||||
@@ -578,11 +401,6 @@ 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
|
||||
}
|
||||
|
||||
@@ -650,11 +468,6 @@ 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))
|
||||
|
||||
@@ -15,23 +15,15 @@ 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.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.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),
|
||||
@@ -108,27 +100,6 @@ 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{
|
||||
@@ -171,236 +142,6 @@ 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_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"),
|
||||
},
|
||||
},
|
||||
"webhook": {
|
||||
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{
|
||||
@@ -621,35 +362,6 @@ 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{
|
||||
@@ -769,27 +481,6 @@ 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{
|
||||
@@ -1198,13 +889,6 @@ 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)",
|
||||
@@ -1214,7 +898,7 @@ func schema_pkg_apis_provisioning_v0alpha1_JobResourceSummary(ref common.Referen
|
||||
},
|
||||
"errors": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Report errors/warnings for this resource type This may not be an exhaustive list and recommend looking at the logs for more info",
|
||||
Description: "Report errors 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{
|
||||
@@ -1227,20 +911,6 @@ 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: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1359,20 +1029,6 @@ 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",
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
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,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
|
||||
@@ -21,8 +18,6 @@ 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,ConnectionSecure,Token
|
||||
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
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package connection
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
githubInstallationURL = "https://github.com/settings/installations"
|
||||
)
|
||||
|
||||
func MutateConnection(connection *provisioning.Connection) error {
|
||||
switch connection.Spec.Type {
|
||||
case provisioning.GithubConnectionType:
|
||||
// Do nothing in case spec.Github is nil.
|
||||
// If this field is required, we should fail at validation time.
|
||||
if connection.Spec.GitHub == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
connection.Spec.URL = fmt.Sprintf("%s/%s", githubInstallationURL, connection.Spec.GitHub.InstallationID)
|
||||
return nil
|
||||
default:
|
||||
// TODO: we need to setup the URL for bitbucket and gitlab.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package connection_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
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"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestMutateConnection(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",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, connection.MutateConnection(c))
|
||||
assert.Equal(t, "https://github.com/settings/installations/456", c.Spec.URL)
|
||||
})
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package connection
|
||||
|
||||
import (
|
||||
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func ValidateConnection(connection *provisioning.Connection) error {
|
||||
list := field.ErrorList{}
|
||||
|
||||
if connection.Spec.Type == "" {
|
||||
list = append(list, field.Required(field.NewPath("spec", "type"), "type must be specified"))
|
||||
}
|
||||
|
||||
switch connection.Spec.Type {
|
||||
case provisioning.GithubConnectionType:
|
||||
list = append(list, validateGithubConnection(connection)...)
|
||||
case provisioning.BitbucketConnectionType:
|
||||
list = append(list, validateBitbucketConnection(connection)...)
|
||||
case provisioning.GitlabConnectionType:
|
||||
list = append(list, validateGitlabConnection(connection)...)
|
||||
default:
|
||||
list = append(
|
||||
list, field.NotSupported(
|
||||
field.NewPath("spec", "type"),
|
||||
connection.Spec.Type,
|
||||
[]provisioning.ConnectionType{
|
||||
provisioning.GithubConnectionType,
|
||||
provisioning.BitbucketConnectionType,
|
||||
provisioning.GitlabConnectionType,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
return toError(connection.GetName(), list)
|
||||
}
|
||||
|
||||
func validateGithubConnection(connection *provisioning.Connection) field.ErrorList {
|
||||
list := field.ErrorList{}
|
||||
|
||||
if connection.Spec.GitHub == nil {
|
||||
list = append(
|
||||
list, field.Required(field.NewPath("spec", "github"), "github info must be specified for GitHub connection"),
|
||||
)
|
||||
}
|
||||
|
||||
if connection.Secure.PrivateKey.IsZero() {
|
||||
list = append(list, field.Required(field.NewPath("secure", "privateKey"), "privateKey must be specified for GitHub connection"))
|
||||
}
|
||||
if !connection.Secure.ClientSecret.IsZero() {
|
||||
list = append(list, field.Forbidden(field.NewPath("secure", "clientSecret"), "clientSecret is forbidden in GitHub connection"))
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
func validateBitbucketConnection(connection *provisioning.Connection) field.ErrorList {
|
||||
list := field.ErrorList{}
|
||||
|
||||
if connection.Spec.Bitbucket == nil {
|
||||
list = append(
|
||||
list, field.Required(field.NewPath("spec", "bitbucket"), "bitbucket info must be specified in Bitbucket connection"),
|
||||
)
|
||||
}
|
||||
if connection.Secure.ClientSecret.IsZero() {
|
||||
list = append(list, field.Required(field.NewPath("secure", "clientSecret"), "clientSecret must be specified for Bitbucket connection"))
|
||||
}
|
||||
if !connection.Secure.PrivateKey.IsZero() {
|
||||
list = append(list, field.Forbidden(field.NewPath("secure", "privateKey"), "privateKey is forbidden in Bitbucket connection"))
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
func validateGitlabConnection(connection *provisioning.Connection) field.ErrorList {
|
||||
list := field.ErrorList{}
|
||||
|
||||
if connection.Spec.Gitlab == nil {
|
||||
list = append(
|
||||
list, field.Required(field.NewPath("spec", "gitlab"), "gitlab info must be specified in Gitlab connection"),
|
||||
)
|
||||
}
|
||||
if connection.Secure.ClientSecret.IsZero() {
|
||||
list = append(list, field.Required(field.NewPath("secure", "clientSecret"), "clientSecret must be specified for Gitlab connection"))
|
||||
}
|
||||
if !connection.Secure.PrivateKey.IsZero() {
|
||||
list = append(list, field.Forbidden(field.NewPath("secure", "privateKey"), "privateKey is forbidden in Gitlab connection"))
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// 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,
|
||||
)
|
||||
}
|
||||
@@ -1,253 +0,0 @@
|
||||
package connection_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
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"
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestValidateConnection(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
connection *provisioning.Connection
|
||||
wantErr bool
|
||||
errMsg string
|
||||
}{
|
||||
{
|
||||
name: "empty type returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "spec.type",
|
||||
},
|
||||
{
|
||||
name: "invalid type returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: "invalid",
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "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,
|
||||
errMsg: "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,
|
||||
errMsg: "secure.privateKey",
|
||||
},
|
||||
{
|
||||
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{
|
||||
PrivateKey: common.InlineSecureValue{
|
||||
Name: "test-private-key",
|
||||
},
|
||||
ClientSecret: common.InlineSecureValue{
|
||||
Name: "test-client-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "secure.clientSecret",
|
||||
},
|
||||
{
|
||||
name: "github type with github 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{
|
||||
Name: "test-private-key",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "bitbucket type without bitbucket config returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.BitbucketConnectionType,
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "spec.bitbucket",
|
||||
},
|
||||
{
|
||||
name: "bitbucket type without client secret returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.BitbucketConnectionType,
|
||||
Bitbucket: &provisioning.BitbucketConnectionConfig{
|
||||
ClientID: "client-123",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "secure.clientSecret",
|
||||
},
|
||||
{
|
||||
name: "bitbucket type with private key returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.BitbucketConnectionType,
|
||||
Bitbucket: &provisioning.BitbucketConnectionConfig{
|
||||
ClientID: "client-123",
|
||||
},
|
||||
},
|
||||
Secure: provisioning.ConnectionSecure{
|
||||
PrivateKey: common.InlineSecureValue{
|
||||
Name: "test-private-key",
|
||||
},
|
||||
ClientSecret: common.InlineSecureValue{
|
||||
Name: "test-client-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "secure.privateKey",
|
||||
},
|
||||
{
|
||||
name: "bitbucket type with bitbucket config is valid",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.BitbucketConnectionType,
|
||||
Bitbucket: &provisioning.BitbucketConnectionConfig{
|
||||
ClientID: "client-123",
|
||||
},
|
||||
},
|
||||
Secure: provisioning.ConnectionSecure{
|
||||
ClientSecret: common.InlineSecureValue{
|
||||
Name: "test-client-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "gitlab type without gitlab config returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.GitlabConnectionType,
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "spec.gitlab",
|
||||
},
|
||||
{
|
||||
name: "gitlab type without client secret returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.GitlabConnectionType,
|
||||
Gitlab: &provisioning.GitlabConnectionConfig{
|
||||
ClientID: "client-456",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "secure.clientSecret",
|
||||
},
|
||||
{
|
||||
name: "gitlab type with private key returns error",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.GitlabConnectionType,
|
||||
Gitlab: &provisioning.GitlabConnectionConfig{
|
||||
ClientID: "client-456",
|
||||
},
|
||||
},
|
||||
Secure: provisioning.ConnectionSecure{
|
||||
PrivateKey: common.InlineSecureValue{
|
||||
Name: "test-private-key",
|
||||
},
|
||||
ClientSecret: common.InlineSecureValue{
|
||||
Name: "test-client-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errMsg: "secure.privateKey",
|
||||
},
|
||||
{
|
||||
name: "gitlab type with gitlab config is valid",
|
||||
connection: &provisioning.Connection{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "test-connection"},
|
||||
Spec: provisioning.ConnectionSpec{
|
||||
Type: provisioning.GitlabConnectionType,
|
||||
Gitlab: &provisioning.GitlabConnectionConfig{
|
||||
ClientID: "client-456",
|
||||
},
|
||||
},
|
||||
Secure: provisioning.ConnectionSecure{
|
||||
ClientSecret: common.InlineSecureValue{
|
||||
Name: "test-client-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := connection.ValidateConnection(tt.connection)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
if tt.errMsg != "" {
|
||||
assert.Contains(t, err.Error(), tt.errMsg)
|
||||
}
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// 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:"webhook,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
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
@@ -7,18 +7,16 @@ 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"`
|
||||
Warning *int64 `json:"warning,omitempty"`
|
||||
Noop *int64 `json:"noop,omitempty"`
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
Warnings []string `json:"warnings,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"`
|
||||
Noop *int64 `json:"noop,omitempty"`
|
||||
Errors []string `json:"errors,omitempty"`
|
||||
}
|
||||
|
||||
// JobResourceSummaryApplyConfiguration constructs a declarative configuration of the JobResourceSummary type for use with
|
||||
@@ -91,14 +89,6 @@ 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.
|
||||
@@ -116,13 +106,3 @@ 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
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ 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"`
|
||||
@@ -70,16 +69,6 @@ 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.
|
||||
|
||||
@@ -18,28 +18,14 @@ 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("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"):
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
// 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{} },
|
||||
),
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// 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,
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,6 @@ 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)
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
package v0alpha1
|
||||
|
||||
type ConnectionExpansion interface{}
|
||||
|
||||
type HistoricJobExpansion interface{}
|
||||
|
||||
type JobExpansion interface{}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
|
||||
type ProvisioningV0alpha1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
ConnectionsGetter
|
||||
HistoricJobsGetter
|
||||
JobsGetter
|
||||
RepositoriesGetter
|
||||
@@ -25,10 +24,6 @@ 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)
|
||||
}
|
||||
|
||||
@@ -39,8 +39,6 @@ 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"):
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
// 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())
|
||||
}
|
||||
@@ -10,8 +10,6 @@ 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.
|
||||
@@ -31,11 +29,6 @@ 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}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// 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]
|
||||
}
|
||||
@@ -4,14 +4,6 @@
|
||||
|
||||
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{}
|
||||
|
||||
@@ -211,12 +211,6 @@ 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.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user