Merge remote-tracking branch 'origin/grafana-git-ui-sync' into feature/unified-onboarding
This commit is contained in:
+12
-15
@@ -5,6 +5,12 @@
|
||||
//
|
||||
exports[`better eslint`] = {
|
||||
value: `{
|
||||
"apps/dashboard/tshack/v0alpha1_spec_gen.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"apps/dashboard/tshack/v1alpha1_spec_gen.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"e2e/old-arch/utils/support/types.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
@@ -2384,10 +2390,8 @@ exports[`better eslint`] = {
|
||||
],
|
||||
"public/app/features/alerting/unified/components/rules/CloudRules.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"]
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
|
||||
],
|
||||
"public/app/features/alerting/unified/components/rules/EditRuleGroupModal.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
|
||||
@@ -2959,10 +2963,6 @@ exports[`better eslint`] = {
|
||||
"public/app/features/auth-config/utils/data.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/browse-dashboards/BrowseDashboardsPage.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
|
||||
],
|
||||
"public/app/features/browse-dashboards/api/browseDashboardsAPI.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`@reduxjs/toolkit/query/react\`)", "0"]
|
||||
],
|
||||
@@ -2977,7 +2977,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
|
||||
],
|
||||
"public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
|
||||
@@ -2987,14 +2987,15 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "7"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "8"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "9"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "10"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "11"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "12"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "14"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "17"]
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "17"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "18"]
|
||||
],
|
||||
"public/app/features/browse-dashboards/state/index.ts:5381": [
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"],
|
||||
@@ -6061,10 +6062,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
|
||||
],
|
||||
"public/app/features/scopes/index.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`./ScopesDashboards\`)", "0"],
|
||||
[0, 0, 0, "Do not re-export imported variable (\`./instance\`)", "1"]
|
||||
],
|
||||
"public/app/features/search/page/components/ActionRow.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
|
||||
+103
-103
@@ -25,7 +25,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build verify-drone
|
||||
@@ -75,7 +75,7 @@ steps:
|
||||
- go install github.com/bazelbuild/buildtools/buildifier@latest
|
||||
- buildifier --lint=warn -mode=check -r .
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: lint-starlark
|
||||
trigger:
|
||||
event:
|
||||
@@ -437,7 +437,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -446,21 +446,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -469,7 +469,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
event:
|
||||
@@ -524,7 +524,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $(/usr/bin/github-app-external-token) > /github-app/token
|
||||
@@ -569,16 +569,16 @@ steps:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- go run scripts/modowners/modowners.go check go.mod
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: validate-modfile
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make swagger-validate
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: validate-openapi-spec
|
||||
trigger:
|
||||
event:
|
||||
@@ -655,7 +655,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -665,7 +665,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -674,7 +674,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -712,7 +712,7 @@ steps:
|
||||
- /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64
|
||||
-a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu
|
||||
-a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7
|
||||
-a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.7 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
-a docker:grafana:linux/arm/v7:ubuntu --go-version=1.24.1 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
--build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.21.3
|
||||
--tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{
|
||||
.version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD
|
||||
@@ -1110,7 +1110,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
@@ -1124,7 +1124,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -1133,14 +1133,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -1161,7 +1161,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -1182,7 +1182,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -1198,7 +1198,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -1214,7 +1214,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -1230,7 +1230,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
event:
|
||||
@@ -1312,7 +1312,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
trigger:
|
||||
event:
|
||||
@@ -1433,7 +1433,7 @@ steps:
|
||||
&& return 1; fi
|
||||
depends_on:
|
||||
- clone-enterprise
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: swagger-gen
|
||||
trigger:
|
||||
event:
|
||||
@@ -1538,7 +1538,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -1549,7 +1549,7 @@ steps:
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on:
|
||||
- clone-enterprise
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -1559,14 +1559,14 @@ steps:
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on:
|
||||
- clone-enterprise
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1574,7 +1574,7 @@ steps:
|
||||
- go test -v -run=^$ -benchmem -timeout=1h -count=8 -bench=. ${GO_PACKAGES}
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: sqlite-benchmark-integration-tests
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1586,7 +1586,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: postgres-benchmark-integration-tests
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1597,7 +1597,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: mysql-8.0-benchmark-integration-tests
|
||||
trigger:
|
||||
event:
|
||||
@@ -1669,7 +1669,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
trigger:
|
||||
branch: main
|
||||
@@ -1852,7 +1852,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -1861,21 +1861,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1884,7 +1884,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
branch: main
|
||||
@@ -1929,22 +1929,22 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- go run scripts/modowners/modowners.go check go.mod
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: validate-modfile
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make swagger-validate
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: validate-openapi-spec
|
||||
- commands:
|
||||
- ./bin/build verify-drone
|
||||
@@ -2076,7 +2076,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -2086,7 +2086,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -2095,7 +2095,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -2132,7 +2132,7 @@ steps:
|
||||
- /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64
|
||||
-a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu
|
||||
-a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7
|
||||
-a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.7 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
-a docker:grafana:linux/arm/v7:ubuntu --go-version=1.24.1 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
--build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.21.3
|
||||
--tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{
|
||||
.version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD
|
||||
@@ -2607,7 +2607,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
@@ -2621,7 +2621,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -2630,14 +2630,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -2658,7 +2658,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -2679,7 +2679,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -2695,7 +2695,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -2711,7 +2711,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -2727,7 +2727,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
branch: main
|
||||
@@ -2996,7 +2996,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -3005,21 +3005,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -3028,7 +3028,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
branch:
|
||||
@@ -3071,22 +3071,22 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- go run scripts/modowners/modowners.go check go.mod
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: validate-modfile
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make swagger-validate
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: validate-openapi-spec
|
||||
trigger:
|
||||
branch:
|
||||
@@ -3165,7 +3165,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
@@ -3179,7 +3179,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -3188,14 +3188,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -3216,7 +3216,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -3237,7 +3237,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -3253,7 +3253,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -3269,7 +3269,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -3285,7 +3285,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
branch:
|
||||
@@ -3385,7 +3385,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build artifacts docker fetch --edition oss
|
||||
@@ -3517,7 +3517,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build artifacts docker fetch --edition oss
|
||||
@@ -3658,7 +3658,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build artifacts packages --artifacts-editions=oss --tag $${DRONE_TAG} --src-bucket
|
||||
@@ -3750,7 +3750,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -3850,7 +3850,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- depends_on:
|
||||
- compile-build-cmd
|
||||
@@ -3947,7 +3947,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build publish grafana-com --edition oss ${DRONE_TAG}
|
||||
@@ -4009,7 +4009,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.7
|
||||
GO_VERSION: 1.24.1
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4084,7 +4084,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.7
|
||||
GO_VERSION: 1.24.1
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4201,7 +4201,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.7
|
||||
GO_VERSION: 1.24.1
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4352,7 +4352,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -4361,21 +4361,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -4384,7 +4384,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
cron:
|
||||
@@ -4438,7 +4438,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.7
|
||||
GO_VERSION: 1.24.1
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4582,7 +4582,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.7
|
||||
GO_VERSION: 1.24.1
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4689,7 +4689,7 @@ steps:
|
||||
- export GITHUB_TOKEN=$(cat /github-app/token)
|
||||
- dagger run --silent /src/grafana-build artifacts -a $${ARTIFACTS} --grafana-ref=$${GRAFANA_REF}
|
||||
--enterprise-ref=$${ENTERPRISE_REF} --grafana-repo=$${GRAFANA_REPO} --version=$${VERSION}
|
||||
--go-version=1.23.7
|
||||
--go-version=1.24.1
|
||||
depends_on:
|
||||
- github-app-generate-token
|
||||
environment:
|
||||
@@ -4710,7 +4710,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.7
|
||||
GO_VERSION: 1.24.1
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4848,7 +4848,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -4857,14 +4857,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -4885,7 +4885,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -4906,7 +4906,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -4922,7 +4922,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -4938,7 +4938,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -4954,7 +4954,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.7-alpine
|
||||
image: golang:1.24.1-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
event:
|
||||
@@ -5257,7 +5257,7 @@ steps:
|
||||
- commands:
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM docker:27-cli
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine/git:2.40.1
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.23.7-alpine
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.24.1-alpine
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22.11.0-alpine
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22-bookworm
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM google/cloud-sdk:431.0.0
|
||||
@@ -5295,7 +5295,7 @@ steps:
|
||||
- commands:
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL docker:27-cli
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL alpine/git:2.40.1
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.23.7-alpine
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.24.1-alpine
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL node:22.11.0-alpine
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL node:22-bookworm
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL google/cloud-sdk:431.0.0
|
||||
@@ -5564,6 +5564,6 @@ kind: secret
|
||||
name: gcr_credentials
|
||||
---
|
||||
kind: signature
|
||||
hmac: 33f2e5615dfd7889899f9f8f16f7716190fa637fe98f1efd7e29607f8946be7d
|
||||
hmac: f55fddb4c6faf30b232ae778ec6c022c9f3d32955879e8a764c715642712c5ea
|
||||
|
||||
...
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
/pkg/registry/apis/provisioning @grafana/grafana-git-ui-sync-team
|
||||
|
||||
/apps/alerting/ @grafana/alerting-backend
|
||||
/apps/dashboard/ @grafana/grafana-app-platform-squad @grafana/dashboards-squad
|
||||
/apps/playlist/ @grafana/grafana-app-platform-squad
|
||||
/apps/investigations/ @fcjack @matryer @svennergr
|
||||
/apps/advisor/ @grafana/plugins-platform-backend
|
||||
|
||||
@@ -8,7 +8,7 @@ name: "CodeQL"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [main, v1.8.x, v2.0.x, v2.1.x, v2.6.x, v3.0.x, v3.1.x, v4.0.x, v4.1.x, v4.2.x, v4.3.x, v4.4.x, v4.5.x, v4.6.x, v4.7.x, v5.0.x, v5.1.x, v5.2.x, v5.3.x, v5.4.x, v6.0.x, v6.1.x, v6.2.x, v6.3.x, v6.4.x, v6.5.x, v6.6.x, v6.7.x, v7.0.x, v7.1.x, v7.2.x]
|
||||
branches: [main, v*.*.*]
|
||||
paths-ignore:
|
||||
- '**/*.cue'
|
||||
- '**/*.json'
|
||||
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: "go"
|
||||
|
||||
@@ -50,4 +50,4 @@ jobs:
|
||||
make build-go
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
@@ -28,9 +28,9 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: "javascript"
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
@@ -26,9 +26,9 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: "python"
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
@@ -19,6 +19,9 @@ vendor
|
||||
# TS generate from cue by cuetsy
|
||||
**/*.gen.ts
|
||||
|
||||
# TS generated by grafana-app-sdk
|
||||
**/*_gen.ts
|
||||
|
||||
# Auto-generated theme files
|
||||
theme.light.generated.json
|
||||
theme.dark.generated.json
|
||||
|
||||
@@ -131,14 +131,12 @@ else
|
||||
i18n-extract-enterprise:
|
||||
@echo "Extracting i18n strings for Enterprise"
|
||||
yarn run i18next --config public/locales/i18next-parser-enterprise.config.cjs
|
||||
node ./public/locales/pseudo.mjs --mode enterprise
|
||||
endif
|
||||
|
||||
.PHONY: i18n-extract
|
||||
i18n-extract: i18n-extract-enterprise
|
||||
@echo "Extracting i18n strings for OSS"
|
||||
yarn run i18next --config public/locales/i18next-parser.config.cjs
|
||||
node ./public/locales/pseudo.mjs --mode oss
|
||||
|
||||
##@ Building
|
||||
.PHONY: gen-cue
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"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/infra/log"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@@ -24,6 +25,12 @@ func New(cfg app.Config) (app.App, error) {
|
||||
return nil, fmt.Errorf("invalid config type")
|
||||
}
|
||||
checkRegistry := specificConfig.CheckRegistry
|
||||
stackID := specificConfig.StackID
|
||||
namespace, err := checks.GetNamespace(stackID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log := log.New("advisor.app")
|
||||
|
||||
// Prepare storage client
|
||||
clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{})
|
||||
@@ -60,6 +67,13 @@ func New(cfg app.Config) (app.App, error) {
|
||||
},
|
||||
Watcher: &simple.Watcher{
|
||||
AddFunc: func(ctx context.Context, obj resource.Object) error {
|
||||
log.Debug("Adding check", "namespace", obj.GetNamespace())
|
||||
if obj.GetNamespace() != namespace {
|
||||
log.Debug("Skipping check in namespace", "namespace", obj.GetNamespace())
|
||||
return nil
|
||||
} else {
|
||||
log.Debug("Processing check in namespace", "namespace", obj.GetNamespace())
|
||||
}
|
||||
check, err := getCheck(obj, checkMap)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -62,13 +62,13 @@ require (
|
||||
go.etcd.io/etcd/client/v3 v3.5.16 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
|
||||
@@ -180,22 +180,22 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
.PHONY: generate
|
||||
generate:
|
||||
@grafana-app-sdk generate \
|
||||
--source=./kinds/ \
|
||||
--gogenpath=../../pkg/apis \
|
||||
--tsgenpath=../../packages/grafana-schema/src/schema \
|
||||
--grouping=group \
|
||||
--defencoding=none \
|
||||
--genoperatorstate=false \
|
||||
--noschemasinmanifest
|
||||
|
||||
# This is a workaround for SDK codegen not producing correct output for v0alpha1
|
||||
@rm ../../packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts
|
||||
@cp ./tshack/v0alpha1_spec_gen.ts ../../packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts
|
||||
|
||||
# Same for v1alpha1
|
||||
@rm ../../packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts
|
||||
@cp ./tshack/v1alpha1_spec_gen.ts ../../packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts
|
||||
@@ -0,0 +1,4 @@
|
||||
module: "github.com/grafana/grafana/sdkkinds/dashboard"
|
||||
language: {
|
||||
version: "v0.9.0"
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package kinds
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/sdkkinds/dashboard/v0alpha1"
|
||||
"github.com/grafana/grafana/sdkkinds/dashboard/v1alpha1"
|
||||
"github.com/grafana/grafana/sdkkinds/dashboard/v2alpha1"
|
||||
)
|
||||
|
||||
// Status is the shared status of all dashboard versions.
|
||||
DashboardStatus: {
|
||||
// Optional conversion status.
|
||||
conversion?: ConversionStatus
|
||||
}
|
||||
|
||||
// ConversionStatus is the status of the conversion of the dashboard.
|
||||
ConversionStatus: {
|
||||
// Whether from another version has failed.
|
||||
// If true, means that the dashboard is not valid,
|
||||
// and the caller should instead fetch the stored version.
|
||||
failed: bool
|
||||
|
||||
// The version which was stored when the dashboard was created / updated.
|
||||
// Fetching this version should always succeed.
|
||||
storedVersion: string
|
||||
|
||||
// The error message from the conversion.
|
||||
// Empty if the conversion has not failed.
|
||||
error: string
|
||||
}
|
||||
|
||||
dashboard: {
|
||||
kind: "Dashboard"
|
||||
pluralName: "Dashboards"
|
||||
current: "v0alpha1"
|
||||
|
||||
codegen: {
|
||||
ts: {
|
||||
enabled: true
|
||||
config: {
|
||||
enumsAsUnionTypes: true
|
||||
}
|
||||
}
|
||||
go: {
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
|
||||
versions: {
|
||||
"v0alpha1": {
|
||||
schema: {
|
||||
spec: v0alpha1.DashboardSpec
|
||||
status: DashboardStatus
|
||||
}
|
||||
}
|
||||
"v1alpha1": {
|
||||
schema: {
|
||||
spec: v1alpha1.DashboardSpec
|
||||
status: DashboardStatus
|
||||
}
|
||||
}
|
||||
"v2alpha1": {
|
||||
schema: {
|
||||
spec: v2alpha1.DashboardSpec
|
||||
status: DashboardStatus
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package kinds
|
||||
|
||||
manifest: {
|
||||
appName: "dashboard"
|
||||
groupOverride: "dashboard.grafana.app"
|
||||
kinds: [
|
||||
dashboard,
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package v0alpha1
|
||||
|
||||
// TODO: this outputs nothing.
|
||||
// For now, we use unstructured for the spec,
|
||||
// but it cannot be produced by the SDK codegen.
|
||||
DashboardSpec: [string]: _
|
||||
@@ -0,0 +1,6 @@
|
||||
package v1alpha1
|
||||
|
||||
// TODO: this outputs nothing.
|
||||
// For now, we use unstructured for the spec,
|
||||
// but it cannot be produced by the SDK codegen.
|
||||
DashboardSpec: [string]: _
|
||||
@@ -0,0 +1,923 @@
|
||||
package v2alpha1
|
||||
|
||||
DashboardSpec: {
|
||||
// Title of dashboard.
|
||||
annotations: [...AnnotationQueryKind]
|
||||
|
||||
// Configuration of dashboard cursor sync behavior.
|
||||
// "Off" for no shared crosshair or tooltip (default).
|
||||
// "Crosshair" for shared crosshair.
|
||||
// "Tooltip" for shared crosshair AND shared tooltip.
|
||||
cursorSync: DashboardCursorSync
|
||||
|
||||
// Description of dashboard.
|
||||
description?: string
|
||||
|
||||
// Whether a dashboard is editable or not.
|
||||
editable?: bool | *true
|
||||
|
||||
elements: [ElementReference.name]: Element
|
||||
|
||||
layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind
|
||||
|
||||
// Links with references to other dashboards or external websites.
|
||||
links: [...DashboardLink]
|
||||
|
||||
// When set to true, the dashboard will redraw panels at an interval matching the pixel width.
|
||||
// This will keep data "moving left" regardless of the query refresh rate. This setting helps
|
||||
// avoid dashboards presenting stale live data.
|
||||
liveNow?: bool
|
||||
|
||||
// When set to true, the dashboard will load all panels in the dashboard when it's loaded.
|
||||
preload: bool
|
||||
|
||||
// Plugins only. The version of the dashboard installed together with the plugin.
|
||||
// This is used to determine if the dashboard should be updated when the plugin is updated.
|
||||
revision?: uint16
|
||||
|
||||
// Tags associated with dashboard.
|
||||
tags: [...string]
|
||||
|
||||
timeSettings: TimeSettingsSpec
|
||||
|
||||
// Title of dashboard.
|
||||
title: string
|
||||
|
||||
// Configured template variables.
|
||||
variables: [...VariableKind]
|
||||
}
|
||||
|
||||
// Supported dashboard elements
|
||||
Element: PanelKind | LibraryPanelKind // |* more element types in the future
|
||||
|
||||
LibraryPanelKind: {
|
||||
kind: "LibraryPanel"
|
||||
spec: LibraryPanelKindSpec
|
||||
}
|
||||
|
||||
LibraryPanelKindSpec: {
|
||||
// Panel ID for the library panel in the dashboard
|
||||
id: number
|
||||
// Title for the library panel in the dashboard
|
||||
title: string
|
||||
|
||||
libraryPanel: LibraryPanelRef
|
||||
}
|
||||
|
||||
// A library panel is a reusable panel that you can use in any dashboard.
|
||||
// When you make a change to a library panel, that change propagates to all instances of where the panel is used.
|
||||
// Library panels streamline reuse of panels across multiple dashboards.
|
||||
LibraryPanelRef: {
|
||||
// Library panel name
|
||||
name: string
|
||||
// Library panel uid
|
||||
uid: string
|
||||
}
|
||||
|
||||
AnnotationPanelFilter: {
|
||||
// Should the specified panels be included or excluded
|
||||
exclude?: bool | *false
|
||||
|
||||
// Panel IDs that should be included or excluded
|
||||
ids: [...uint8]
|
||||
}
|
||||
|
||||
// "Off" for no shared crosshair or tooltip (default).
|
||||
// "Crosshair" for shared crosshair.
|
||||
// "Tooltip" for shared crosshair AND shared tooltip.
|
||||
DashboardCursorSync: "Off" | "Crosshair" | "Tooltip"
|
||||
|
||||
// Links with references to other dashboards or external resources
|
||||
DashboardLink: {
|
||||
// Title to display with the link
|
||||
title: string
|
||||
// Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
|
||||
// FIXME: The type is generated as `type: DashboardLinkType | dashboardLinkType.Link;` but it should be `type: DashboardLinkType`
|
||||
type: DashboardLinkType
|
||||
// Icon name to be displayed with the link
|
||||
icon: string
|
||||
// Tooltip to display when the user hovers their mouse over it
|
||||
tooltip: string
|
||||
// Link URL. Only required/valid if the type is link
|
||||
url?: string
|
||||
// List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards
|
||||
tags: [...string]
|
||||
// If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards
|
||||
asDropdown: bool | *false
|
||||
// If true, the link will be opened in a new tab
|
||||
targetBlank: bool | *false
|
||||
// If true, includes current template variables values in the link as query params
|
||||
includeVars: bool | *false
|
||||
// If true, includes current time range in the link as query params
|
||||
keepTime: bool | *false
|
||||
}
|
||||
|
||||
DataSourceRef: {
|
||||
// The plugin type-id
|
||||
type?: string
|
||||
|
||||
// Specific datasource instance
|
||||
uid?: string
|
||||
}
|
||||
|
||||
// A topic is attached to DataFrame metadata in query results.
|
||||
// This specifies where the data should be used.
|
||||
DataTopic: "series" | "annotations" | "alertStates" @cog(kind="enum",memberNames="Series|Annotations|AlertStates")
|
||||
|
||||
// Transformations allow to manipulate data returned by a query before the system applies a visualization.
|
||||
// Using transformations you can: rename fields, join time series data, perform mathematical operations across queries,
|
||||
// use the output of one transformation as the input to another transformation, etc.
|
||||
DataTransformerConfig: {
|
||||
// Unique identifier of transformer
|
||||
id: string
|
||||
// Disabled transformations are skipped
|
||||
disabled?: bool
|
||||
// Optional frame matcher. When missing it will be applied to all results
|
||||
filter?: MatcherConfig
|
||||
// Where to pull DataFrames from as input to transformation
|
||||
topic?: DataTopic
|
||||
// Options to be passed to the transformer
|
||||
// Valid options depend on the transformer id
|
||||
options: _
|
||||
}
|
||||
|
||||
DataLink: {
|
||||
title: string
|
||||
url: string
|
||||
targetBlank?: bool
|
||||
}
|
||||
|
||||
// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.
|
||||
// Each column within this structure is called a field. A field can represent a single time series or table column.
|
||||
// Field options allow you to change how the data is displayed in your visualizations.
|
||||
FieldConfigSource: {
|
||||
// Defaults are the options applied to all fields.
|
||||
defaults: FieldConfig
|
||||
// Overrides are the options applied to specific fields overriding the defaults.
|
||||
overrides: [...{
|
||||
matcher: MatcherConfig
|
||||
properties: [...DynamicConfigValue]
|
||||
}]
|
||||
}
|
||||
|
||||
// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.
|
||||
// Each column within this structure is called a field. A field can represent a single time series or table column.
|
||||
// Field options allow you to change how the data is displayed in your visualizations.
|
||||
FieldConfig: {
|
||||
// The display value for this field. This supports template variables blank is auto
|
||||
displayName?: string
|
||||
|
||||
// This can be used by data sources that return and explicit naming structure for values and labels
|
||||
// When this property is configured, this value is used rather than the default naming strategy.
|
||||
displayNameFromDS?: string
|
||||
|
||||
// Human readable field metadata
|
||||
description?: string
|
||||
|
||||
// An explicit path to the field in the datasource. When the frame meta includes a path,
|
||||
// This will default to `${frame.meta.path}/${field.name}
|
||||
//
|
||||
// When defined, this value can be used as an identifier within the datasource scope, and
|
||||
// may be used to update the results
|
||||
path?: string
|
||||
|
||||
// True if data source can write a value to the path. Auth/authz are supported separately
|
||||
writeable?: bool
|
||||
|
||||
// True if data source field supports ad-hoc filters
|
||||
filterable?: bool
|
||||
|
||||
// Unit a field should use. The unit you select is applied to all fields except time.
|
||||
// You can use the units ID availables in Grafana or a custom unit.
|
||||
// Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts
|
||||
// As custom unit, you can use the following formats:
|
||||
// `suffix:<suffix>` for custom unit that should go after value.
|
||||
// `prefix:<prefix>` for custom unit that should go before value.
|
||||
// `time:<format>` For custom date time formats type for example `time:YYYY-MM-DD`.
|
||||
// `si:<base scale><unit characters>` for custom SI units. For example: `si: mF`. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character.
|
||||
// `count:<unit>` for a custom count unit.
|
||||
// `currency:<unit>` for custom a currency unit.
|
||||
unit?: string
|
||||
|
||||
// Specify the number of decimals Grafana includes in the rendered value.
|
||||
// If you leave this field blank, Grafana automatically truncates the number of decimals based on the value.
|
||||
// For example 1.1234 will display as 1.12 and 100.456 will display as 100.
|
||||
// To display all decimals, set the unit to `String`.
|
||||
decimals?: number
|
||||
|
||||
// The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
|
||||
min?: number
|
||||
// The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.
|
||||
max?: number
|
||||
|
||||
// Convert input values into a display string
|
||||
mappings?: [...ValueMapping]
|
||||
|
||||
// Map numeric values to states
|
||||
thresholds?: ThresholdsConfig
|
||||
|
||||
// Panel color configuration
|
||||
color?: FieldColor
|
||||
|
||||
// The behavior when clicking on a result
|
||||
links?: [...]
|
||||
|
||||
// Alternative to empty string
|
||||
noValue?: string
|
||||
|
||||
// custom is specified by the FieldConfig field
|
||||
// in panel plugin schemas.
|
||||
custom?: {...}
|
||||
}
|
||||
|
||||
DynamicConfigValue: {
|
||||
id: string | *""
|
||||
value?: _
|
||||
}
|
||||
|
||||
// Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation.
|
||||
// It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.
|
||||
MatcherConfig: {
|
||||
// The matcher id. This is used to find the matcher implementation from registry.
|
||||
id: string | *""
|
||||
// The matcher options. This is specific to the matcher implementation.
|
||||
options?: _
|
||||
}
|
||||
|
||||
Threshold: {
|
||||
value: number
|
||||
color: string
|
||||
}
|
||||
|
||||
ThresholdsMode: "absolute" | "percentage"
|
||||
|
||||
ThresholdsConfig: {
|
||||
mode: ThresholdsMode
|
||||
steps: [...Threshold]
|
||||
}
|
||||
|
||||
ValueMapping: ValueMap | RangeMap | RegexMap | SpecialValueMap
|
||||
|
||||
// Supported value mapping types
|
||||
// `value`: Maps text values to a color or different display text and color. For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.
|
||||
// `range`: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.
|
||||
// `regex`: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.
|
||||
// `special`: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.
|
||||
MappingType: "value" | "range" | "regex" | "special" @cog(kind="enum",memberNames="ValueToText|RangeToText|RegexToText|SpecialValue")
|
||||
|
||||
// Maps text values to a color or different display text and color.
|
||||
// For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.
|
||||
ValueMap: {
|
||||
// TODO (@radiohead): Something broke in cog / app SDK codegen
|
||||
// And this is no longer producing valid TS / Go output
|
||||
// type: MappingType & "value"
|
||||
type: "value"
|
||||
// Map with <value_to_match>: ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } }
|
||||
options: [string]: ValueMappingResult
|
||||
}
|
||||
|
||||
// Maps numerical ranges to a display text and color.
|
||||
// For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.
|
||||
RangeMap: {
|
||||
// TODO (@radiohead): Something broke in cog / app SDK codegen
|
||||
// And this is no longer producing valid TS / Go output
|
||||
// type: MappingType & "range"
|
||||
type: "range"
|
||||
// Range to match against and the result to apply when the value is within the range
|
||||
options: {
|
||||
// Min value of the range. It can be null which means -Infinity
|
||||
from: float64 | null
|
||||
// Max value of the range. It can be null which means +Infinity
|
||||
to: float64 | null
|
||||
// Config to apply when the value is within the range
|
||||
result: ValueMappingResult
|
||||
}
|
||||
}
|
||||
|
||||
// Maps regular expressions to replacement text and a color.
|
||||
// For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.
|
||||
RegexMap: {
|
||||
// TODO (@radiohead): Something broke in cog / app SDK codegen
|
||||
// And this is no longer producing valid TS / Go output
|
||||
// type: MappingType & "regex"
|
||||
type: "regex"
|
||||
// Regular expression to match against and the result to apply when the value matches the regex
|
||||
options: {
|
||||
// Regular expression to match against
|
||||
pattern: string
|
||||
// Config to apply when the value matches the regex
|
||||
result: ValueMappingResult
|
||||
}
|
||||
}
|
||||
|
||||
// Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color.
|
||||
// See SpecialValueMatch to see the list of special values.
|
||||
// For example, you can configure a special value mapping so that null values appear as N/A.
|
||||
SpecialValueMap: {
|
||||
// TODO (@radiohead): Something broke in cog / app SDK codegen
|
||||
// And this is no longer producing valid TS / Go output
|
||||
// type: MappingType & "special"
|
||||
type: "special"
|
||||
options: {
|
||||
// Special value to match against
|
||||
match: SpecialValueMatch
|
||||
// Config to apply when the value matches the special value
|
||||
result: ValueMappingResult
|
||||
}
|
||||
}
|
||||
|
||||
// Special value types supported by the `SpecialValueMap`
|
||||
SpecialValueMatch: "true" | "false" | "null" | "nan" | "null+nan" | "empty" @cog(kind="enum",memberNames="True|False|Null|NaN|NullAndNaN|Empty")
|
||||
|
||||
// Result used as replacement with text and color when the value matches
|
||||
ValueMappingResult: {
|
||||
// Text to display when the value matches
|
||||
text?: string
|
||||
// Text to use when the value matches
|
||||
color?: string
|
||||
// Icon to display when the value matches. Only specific visualizations.
|
||||
icon?: string
|
||||
// Position in the mapping array. Only used internally.
|
||||
index?: int32
|
||||
}
|
||||
|
||||
// Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value.
|
||||
// Continuous color interpolates a color using the percentage of a value relative to min and max.
|
||||
// Accepted values are:
|
||||
// `thresholds`: From thresholds. Informs Grafana to take the color from the matching threshold
|
||||
// `palette-classic`: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations
|
||||
// `palette-classic-by-name`: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations
|
||||
// `continuous-GrYlRd`: ontinuous Green-Yellow-Red palette mode
|
||||
// `continuous-RdYlGr`: Continuous Red-Yellow-Green palette mode
|
||||
// `continuous-BlYlRd`: Continuous Blue-Yellow-Red palette mode
|
||||
// `continuous-YlRd`: Continuous Yellow-Red palette mode
|
||||
// `continuous-BlPu`: Continuous Blue-Purple palette mode
|
||||
// `continuous-YlBl`: Continuous Yellow-Blue palette mode
|
||||
// `continuous-blues`: Continuous Blue palette mode
|
||||
// `continuous-reds`: Continuous Red palette mode
|
||||
// `continuous-greens`: Continuous Green palette mode
|
||||
// `continuous-purples`: Continuous Purple palette mode
|
||||
// `shades`: Shades of a single color. Specify a single color, useful in an override rule.
|
||||
// `fixed`: Fixed color mode. Specify a single color, useful in an override rule.
|
||||
FieldColorModeId: "thresholds" | "palette-classic" | "palette-classic-by-name" | "continuous-GrYlRd" | "continuous-RdYlGr" | "continuous-BlYlRd" | "continuous-YlRd" | "continuous-BlPu" | "continuous-YlBl" | "continuous-blues" | "continuous-reds" | "continuous-greens" | "continuous-purples" | "fixed" | "shades"
|
||||
|
||||
// Defines how to assign a series color from "by value" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value.
|
||||
FieldColorSeriesByMode: "min" | "max" | "last"
|
||||
|
||||
// Map a field to a color.
|
||||
FieldColor: {
|
||||
// The main color scheme mode.
|
||||
mode: FieldColorModeId
|
||||
// The fixed color value for fixed or shades color modes.
|
||||
fixedColor?: string
|
||||
// Some visualizations need to know how to assign a series color from by value color schemes.
|
||||
seriesBy?: FieldColorSeriesByMode
|
||||
}
|
||||
|
||||
// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
|
||||
DashboardLinkType: "link" | "dashboards"
|
||||
|
||||
// --- Common types ---
|
||||
Kind: {
|
||||
kind: string
|
||||
spec: _
|
||||
metadata?: _
|
||||
}
|
||||
|
||||
// --- Kinds ---
|
||||
VizConfigSpec: {
|
||||
pluginVersion: string
|
||||
options: [string]: _
|
||||
fieldConfig: FieldConfigSource
|
||||
}
|
||||
|
||||
VizConfigKind: {
|
||||
// The kind of a VizConfigKind is the plugin ID
|
||||
kind: string
|
||||
spec: VizConfigSpec
|
||||
}
|
||||
|
||||
AnnotationQuerySpec: {
|
||||
datasource?: DataSourceRef
|
||||
query?: DataQueryKind
|
||||
enable: bool
|
||||
hide: bool
|
||||
iconColor: string
|
||||
name: string
|
||||
builtIn?: bool | *false
|
||||
filter?: AnnotationPanelFilter
|
||||
}
|
||||
|
||||
AnnotationQueryKind: {
|
||||
kind: "AnnotationQuery"
|
||||
spec: AnnotationQuerySpec
|
||||
}
|
||||
|
||||
QueryOptionsSpec: {
|
||||
timeFrom?: string
|
||||
maxDataPoints?: int
|
||||
timeShift?: string
|
||||
queryCachingTTL?: int
|
||||
interval?: string
|
||||
cacheTimeout?: string
|
||||
hideTimeOverride?: bool
|
||||
}
|
||||
|
||||
DataQueryKind: {
|
||||
// The kind of a DataQueryKind is the datasource type
|
||||
kind: string
|
||||
spec: [string]: _
|
||||
}
|
||||
|
||||
PanelQuerySpec: {
|
||||
query: DataQueryKind
|
||||
datasource?: DataSourceRef
|
||||
|
||||
refId: string
|
||||
hidden: bool
|
||||
}
|
||||
|
||||
PanelQueryKind: {
|
||||
kind: "PanelQuery"
|
||||
spec: PanelQuerySpec
|
||||
}
|
||||
|
||||
TransformationKind: {
|
||||
// The kind of a TransformationKind is the transformation ID
|
||||
kind: string
|
||||
spec: DataTransformerConfig
|
||||
}
|
||||
|
||||
QueryGroupSpec: {
|
||||
queries: [...PanelQueryKind]
|
||||
transformations: [...TransformationKind]
|
||||
queryOptions: QueryOptionsSpec
|
||||
}
|
||||
|
||||
QueryGroupKind: {
|
||||
kind: "QueryGroup"
|
||||
spec: QueryGroupSpec
|
||||
}
|
||||
|
||||
TimeRangeOption: {
|
||||
display: string | *"Last 6 hours"
|
||||
from: string | *"now-6h"
|
||||
to: string | *"now"
|
||||
}
|
||||
|
||||
// Time configuration
|
||||
// It defines the default time config for the time picker, the refresh picker for the specific dashboard.
|
||||
TimeSettingsSpec: {
|
||||
// Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc".
|
||||
timezone?: string | *"browser"
|
||||
// Start time range for dashboard.
|
||||
// Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z".
|
||||
from: string | *"now-6h"
|
||||
// End time range for dashboard.
|
||||
// Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z".
|
||||
to: string | *"now"
|
||||
// Refresh rate of dashboard. Represented via interval string, e.g. "5s", "1m", "1h", "1d".
|
||||
autoRefresh: string // v1: refresh
|
||||
// Interval options available in the refresh picker dropdown.
|
||||
autoRefreshIntervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] // v1: timepicker.refresh_intervals
|
||||
// Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard.
|
||||
quickRanges?: [...TimeRangeOption] // v1: timepicker.quick_ranges , not exposed in the UI
|
||||
// Whether timepicker is visible or not.
|
||||
hideTimepicker: bool // v1: timepicker.hidden
|
||||
// Day when the week starts. Expressed by the name of the day in lowercase, e.g. "monday".
|
||||
weekStart?: "saturday" | "monday" | "sunday"
|
||||
// The month that the fiscal year starts on. 0 = January, 11 = December
|
||||
fiscalYearStartMonth: int
|
||||
// Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values.
|
||||
nowDelay?: string // v1: timepicker.nowDelay
|
||||
}
|
||||
|
||||
RepeatMode: "variable" // other repeat modes will be added in the future: label, frame
|
||||
|
||||
RepeatOptions: {
|
||||
mode: RepeatMode
|
||||
value: string
|
||||
direction?: "h" | "v"
|
||||
maxPerRow?: int
|
||||
}
|
||||
|
||||
RowRepeatOptions: {
|
||||
mode: RepeatMode
|
||||
value: string
|
||||
}
|
||||
|
||||
ResponsiveGridRepeatOptions: {
|
||||
mode: RepeatMode
|
||||
value: string
|
||||
}
|
||||
|
||||
GridLayoutItemSpec: {
|
||||
x: int
|
||||
y: int
|
||||
width: int
|
||||
height: int
|
||||
element: ElementReference // reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference
|
||||
repeat?: RepeatOptions
|
||||
}
|
||||
|
||||
GridLayoutItemKind: {
|
||||
kind: "GridLayoutItem"
|
||||
spec: GridLayoutItemSpec
|
||||
}
|
||||
|
||||
GridLayoutRowKind: {
|
||||
kind: "GridLayoutRow"
|
||||
spec: GridLayoutRowSpec
|
||||
}
|
||||
|
||||
GridLayoutRowSpec: {
|
||||
y: int
|
||||
collapsed: bool
|
||||
title: string
|
||||
elements: [...GridLayoutItemKind] // Grid items in the row will have their Y value be relative to the rows Y value. This means a panel positioned at Y: 0 in a row with Y: 10 will be positioned at Y: 11 (row header has a heigh of 1) in the dashboard.
|
||||
repeat?: RowRepeatOptions
|
||||
}
|
||||
|
||||
GridLayoutSpec: {
|
||||
items: [...GridLayoutItemKind | GridLayoutRowKind]
|
||||
}
|
||||
|
||||
GridLayoutKind: {
|
||||
kind: "GridLayout"
|
||||
spec: GridLayoutSpec
|
||||
}
|
||||
|
||||
RowsLayoutKind: {
|
||||
kind: "RowsLayout"
|
||||
spec: RowsLayoutSpec
|
||||
}
|
||||
|
||||
RowsLayoutSpec: {
|
||||
rows: [...RowsLayoutRowKind]
|
||||
}
|
||||
|
||||
RowsLayoutRowKind: {
|
||||
kind: "RowsLayoutRow"
|
||||
spec: RowsLayoutRowSpec
|
||||
}
|
||||
|
||||
RowsLayoutRowSpec: {
|
||||
title?: string
|
||||
collapsed: bool
|
||||
repeat?: RowRepeatOptions
|
||||
layout: GridLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind
|
||||
}
|
||||
|
||||
ResponsiveGridLayoutKind: {
|
||||
kind: "ResponsiveGridLayout"
|
||||
spec: ResponsiveGridLayoutSpec
|
||||
}
|
||||
|
||||
ResponsiveGridLayoutSpec: {
|
||||
row: string
|
||||
col: string
|
||||
items: [...ResponsiveGridLayoutItemKind]
|
||||
}
|
||||
|
||||
ResponsiveGridLayoutItemKind: {
|
||||
kind: "ResponsiveGridLayoutItem"
|
||||
spec: ResponsiveGridLayoutItemSpec
|
||||
}
|
||||
|
||||
ResponsiveGridLayoutItemSpec: {
|
||||
element: ElementReference
|
||||
repeat?: ResponsiveGridRepeatOptions
|
||||
}
|
||||
|
||||
TabsLayoutKind: {
|
||||
kind: "TabsLayout"
|
||||
spec: TabsLayoutSpec
|
||||
}
|
||||
|
||||
TabsLayoutSpec: {
|
||||
tabs: [...TabsLayoutTabKind]
|
||||
}
|
||||
|
||||
TabsLayoutTabKind: {
|
||||
kind: "TabsLayoutTab"
|
||||
spec: TabsLayoutTabSpec
|
||||
}
|
||||
|
||||
TabsLayoutTabSpec: {
|
||||
title?: string
|
||||
layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind
|
||||
}
|
||||
|
||||
PanelSpec: {
|
||||
id: number
|
||||
title: string
|
||||
description: string
|
||||
links: [...DataLink]
|
||||
data: QueryGroupKind
|
||||
vizConfig: VizConfigKind
|
||||
transparent?: bool
|
||||
}
|
||||
|
||||
PanelKind: {
|
||||
kind: "Panel"
|
||||
spec: PanelSpec
|
||||
}
|
||||
|
||||
ElementReference: {
|
||||
kind: "ElementReference"
|
||||
name: string
|
||||
}
|
||||
|
||||
// Start FIXME: variables - in CUE PR - this are things that should be added into the cue schema
|
||||
// TODO: properties such as `hide`, `skipUrlSync`, `multi` are type boolean, and in the old schema they are conditional,
|
||||
// should we make them conditional in the new schema as well? or should we make them required but default to false?
|
||||
|
||||
// Variable types
|
||||
VariableValue: VariableValueSingle | [...VariableValueSingle]
|
||||
|
||||
VariableValueSingle: string | bool | number | CustomVariableValue
|
||||
|
||||
// Custom formatter variable
|
||||
CustomFormatterVariable: {
|
||||
name: string
|
||||
type: VariableType
|
||||
multi: bool
|
||||
includeAll: bool
|
||||
}
|
||||
|
||||
// Custom variable value
|
||||
CustomVariableValue: {
|
||||
// The format name or function used in the expression
|
||||
formatter: *null | string | VariableCustomFormatterFn
|
||||
}
|
||||
|
||||
// Custom formatter function
|
||||
VariableCustomFormatterFn: {
|
||||
value: _
|
||||
legacyVariableModel: {
|
||||
name: string
|
||||
type: VariableType
|
||||
multi: bool
|
||||
includeAll: bool
|
||||
}
|
||||
legacyDefaultFormatter?: VariableCustomFormatterFn
|
||||
}
|
||||
|
||||
// Dashboard variable type
|
||||
// `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on.
|
||||
// `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only).
|
||||
// `constant`: Define a hidden constant.
|
||||
// `datasource`: Quickly change the data source for an entire dashboard.
|
||||
// `interval`: Interval variables represent time spans.
|
||||
// `textbox`: Display a free text input field with an optional default value.
|
||||
// `custom`: Define the variable options manually using a comma-separated list.
|
||||
// `system`: Variables defined by Grafana. See: https://grafana.com/docs/grafana/latest/dashboards/variables/add-template-variables/#global-variables
|
||||
VariableType: "query" | "adhoc" | "groupby" | "constant" | "datasource" | "interval" | "textbox" | "custom" |
|
||||
"system" | "snapshot"
|
||||
|
||||
VariableKind: QueryVariableKind | TextVariableKind | ConstantVariableKind | DatasourceVariableKind | IntervalVariableKind | CustomVariableKind | GroupByVariableKind | AdhocVariableKind
|
||||
|
||||
// Sort variable options
|
||||
// Accepted values are:
|
||||
// `disabled`: No sorting
|
||||
// `alphabeticalAsc`: Alphabetical ASC
|
||||
// `alphabeticalDesc`: Alphabetical DESC
|
||||
// `numericalAsc`: Numerical ASC
|
||||
// `numericalDesc`: Numerical DESC
|
||||
// `alphabeticalCaseInsensitiveAsc`: Alphabetical Case Insensitive ASC
|
||||
// `alphabeticalCaseInsensitiveDesc`: Alphabetical Case Insensitive DESC
|
||||
// `naturalAsc`: Natural ASC
|
||||
// `naturalDesc`: Natural DESC
|
||||
// VariableSort enum with default value
|
||||
VariableSort: "disabled" | "alphabeticalAsc" | "alphabeticalDesc" | "numericalAsc" | "numericalDesc" | "alphabeticalCaseInsensitiveAsc" | "alphabeticalCaseInsensitiveDesc" | "naturalAsc" | "naturalDesc"
|
||||
|
||||
// Options to config when to refresh a variable
|
||||
// `never`: Never refresh the variable
|
||||
// `onDashboardLoad`: Queries the data source every time the dashboard loads.
|
||||
// `onTimeRangeChanged`: Queries the data source when the dashboard time range changes.
|
||||
VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged"
|
||||
|
||||
// Determine if the variable shows on dashboard
|
||||
// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing).
|
||||
VariableHide: *"dontHide" | "hideLabel" | "hideVariable"
|
||||
|
||||
// FIXME: should we introduce this? --- Variable value option
|
||||
VariableValueOption: {
|
||||
label: string
|
||||
value: VariableValueSingle
|
||||
group?: string
|
||||
}
|
||||
|
||||
// Variable option specification
|
||||
VariableOption: {
|
||||
// Whether the option is selected or not
|
||||
selected?: bool
|
||||
// Text to be displayed for the option
|
||||
text: string | [...string]
|
||||
// Value of the option
|
||||
value: string | [...string]
|
||||
}
|
||||
|
||||
// Query variable specification
|
||||
QueryVariableSpec: {
|
||||
name: string | *""
|
||||
current: VariableOption | *{
|
||||
text: ""
|
||||
value: ""
|
||||
}
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
refresh: VariableRefresh
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
datasource?: DataSourceRef
|
||||
query: DataQueryKind
|
||||
regex: string | *""
|
||||
sort: VariableSort
|
||||
definition?: string
|
||||
options: [...VariableOption] | *[]
|
||||
multi: bool | *false
|
||||
includeAll: bool | *false
|
||||
allValue?: string
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
// Query variable kind
|
||||
QueryVariableKind: {
|
||||
kind: "QueryVariable"
|
||||
spec: QueryVariableSpec
|
||||
}
|
||||
|
||||
// Text variable specification
|
||||
TextVariableSpec: {
|
||||
name: string | *""
|
||||
current: VariableOption | *{
|
||||
text: ""
|
||||
value: ""
|
||||
}
|
||||
query: string | *""
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
}
|
||||
|
||||
// Text variable kind
|
||||
TextVariableKind: {
|
||||
kind: "TextVariable"
|
||||
spec: TextVariableSpec
|
||||
}
|
||||
|
||||
// Constant variable specification
|
||||
ConstantVariableSpec: {
|
||||
name: string | *""
|
||||
query: string | *""
|
||||
current: VariableOption | *{
|
||||
text: ""
|
||||
value: ""
|
||||
}
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
}
|
||||
|
||||
// Constant variable kind
|
||||
ConstantVariableKind: {
|
||||
kind: "ConstantVariable"
|
||||
spec: ConstantVariableSpec
|
||||
}
|
||||
|
||||
// Datasource variable specification
|
||||
DatasourceVariableSpec: {
|
||||
name: string | *""
|
||||
pluginId: string | *""
|
||||
refresh: VariableRefresh
|
||||
regex: string | *""
|
||||
current: VariableOption | *{
|
||||
text: ""
|
||||
value: ""
|
||||
}
|
||||
options: [...VariableOption] | *[]
|
||||
multi: bool | *false
|
||||
includeAll: bool | *false
|
||||
allValue?: string
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
}
|
||||
|
||||
// Datasource variable kind
|
||||
DatasourceVariableKind: {
|
||||
kind: "DatasourceVariable"
|
||||
spec: DatasourceVariableSpec
|
||||
}
|
||||
|
||||
// Interval variable specification
|
||||
IntervalVariableSpec: {
|
||||
name: string | *""
|
||||
query: string | *""
|
||||
current: VariableOption | *{
|
||||
text: ""
|
||||
value: ""
|
||||
}
|
||||
options: [...VariableOption] | *[]
|
||||
auto: bool | *false
|
||||
auto_min: string | *""
|
||||
auto_count: int | *0
|
||||
refresh: VariableRefresh
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
}
|
||||
|
||||
// Interval variable kind
|
||||
IntervalVariableKind: {
|
||||
kind: "IntervalVariable"
|
||||
spec: IntervalVariableSpec
|
||||
}
|
||||
|
||||
// Custom variable specification
|
||||
CustomVariableSpec: {
|
||||
name: string | *""
|
||||
query: string | *""
|
||||
current: VariableOption
|
||||
options: [...VariableOption] | *[]
|
||||
multi: bool | *false
|
||||
includeAll: bool | *false
|
||||
allValue?: string
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
}
|
||||
|
||||
// Custom variable kind
|
||||
CustomVariableKind: {
|
||||
kind: "CustomVariable"
|
||||
spec: CustomVariableSpec
|
||||
}
|
||||
|
||||
// GroupBy variable specification
|
||||
GroupByVariableSpec: {
|
||||
name: string | *""
|
||||
datasource?: DataSourceRef
|
||||
current: VariableOption | *{
|
||||
text: ""
|
||||
value: ""
|
||||
}
|
||||
options: [...VariableOption] | *[]
|
||||
multi: bool | *false
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
}
|
||||
|
||||
// Group variable kind
|
||||
GroupByVariableKind: {
|
||||
kind: "GroupByVariable"
|
||||
spec: GroupByVariableSpec
|
||||
}
|
||||
|
||||
// Adhoc variable specification
|
||||
AdhocVariableSpec: {
|
||||
name: string | *""
|
||||
datasource?: DataSourceRef
|
||||
baseFilters: [...AdHocFilterWithLabels] | *[]
|
||||
filters: [...AdHocFilterWithLabels] | *[]
|
||||
defaultKeys: [...MetricFindValue] | *[]
|
||||
label?: string
|
||||
hide: VariableHide
|
||||
skipUrlSync: bool | *false
|
||||
description?: string
|
||||
}
|
||||
|
||||
// Define the MetricFindValue type
|
||||
MetricFindValue: {
|
||||
text: string
|
||||
value?: string | number
|
||||
group?: string
|
||||
expandable?: bool
|
||||
}
|
||||
|
||||
// Define the AdHocFilterWithLabels type
|
||||
AdHocFilterWithLabels: {
|
||||
key: string
|
||||
operator: string
|
||||
value: string
|
||||
values?: [...string]
|
||||
keyLabel?: string
|
||||
valueLabels?: [...string]
|
||||
forceEdit?: bool
|
||||
// @deprecated
|
||||
condition?: string
|
||||
}
|
||||
|
||||
// Adhoc variable kind
|
||||
AdhocVariableKind: {
|
||||
kind: "AdhocVariable"
|
||||
spec: AdhocVariableSpec
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
export interface Spec {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export const defaultSpec = (): Spec => ({});
|
||||
@@ -0,0 +1,7 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
export interface Spec {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export const defaultSpec = (): Spec => ({});
|
||||
@@ -56,13 +56,14 @@ require (
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/net v0.36.0 // indirect
|
||||
golang.org/x/oauth2 v0.27.0 // indirect
|
||||
|
||||
+10
-10
@@ -126,22 +126,22 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
|
||||
@@ -57,13 +57,14 @@ require (
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/net v0.36.0 // indirect
|
||||
golang.org/x/oauth2 v0.27.0 // indirect
|
||||
|
||||
+10
-10
@@ -126,22 +126,22 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
|
||||
@@ -1534,9 +1534,6 @@ timeout = 10s
|
||||
# Only has effect if the grafanaManagedRecordRulesDatasources feature toggle is enabled.
|
||||
default_datasource_uid =
|
||||
|
||||
# Suffix to apply to the data source URL for remote write requests.
|
||||
remote_write_path_suffix = /push
|
||||
|
||||
# Optional custom headers to include in recording rule write requests.
|
||||
[recording_rules.custom_headers]
|
||||
# exampleHeader = exampleValue
|
||||
|
||||
@@ -1516,9 +1516,6 @@ timeout = 30s
|
||||
# Only has effect if the grafanaManagedRecordRulesDatasources feature toggle is enabled.
|
||||
default_datasource_uid =
|
||||
|
||||
# Suffix to apply to the data source URL for remote write requests.
|
||||
remote_write_path_suffix = /push
|
||||
|
||||
# Optional custom headers to include in recording rule write requests.
|
||||
[recording_rules.custom_headers]
|
||||
# exampleHeader = exampleValue
|
||||
|
||||
@@ -147,6 +147,12 @@ Your data sources, including credentials, are migrated securely and seamlessly t
|
||||
|
||||
The migration assistant supports any plugins found in the plugins catalog. As long as the plugin is signed or is a core plugin built into Grafana, it is eligible for migration. Due to security reasons, unsigned plugins are not supported in Grafana Cloud. If you are using any unsigned private plugins, Grafana recommends you seek an alternative plugin for the catalog or work on a strategy to deprecate certain functionality from your self-managed instance.
|
||||
|
||||
Upgrade any plugins you intend to migrate before using the migration assistant as any migrated plugins will be configured on the Grafana Cloud instance as the latest version of that plugin.
|
||||
|
||||
{{< admonition type="caution">}}
|
||||
If you want to migrate Enterprise plugins, check what type of plan your Grafana Cloud instance is on and whether or not this plan requires an Enterprise plugin add-on.
|
||||
{{< /admonition >}}
|
||||
|
||||
### Grafana Alerting resources
|
||||
|
||||
The migration assistant can migrate the majority of Grafana Alerting resources to your Grafana Cloud instance. These include:
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ To learn how to use the roles API to determine the role UUIDs, refer to [Manage
|
||||
| `fixed:authentication.config:writer` | `fixed_0rYhZ2Qnzs8AdB1nX7gexk3fHDw` | `settings:read` for scope `settings:auth.saml:*` <br> `settings:write` for scope `settings:auth.saml:*` | Read and update authentication and SAML settings. |
|
||||
| `fixed:dashboards:creator` | `fixed_ZorKUcEPCM01A1fPakEzGBUyU64` | `dashboards:create`<br>`folders:read` | Create dashboards. |
|
||||
| `fixed:dashboards:reader` | `fixed_Sgr67JTOhjQGFlzYRahOe45TdWM` | `dashboards:read` | Read all dashboards. |
|
||||
| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and <br>`dashboards:write`<br>`dashboards:edit`<br>`dashboards:delete`<br>`dashboards:create`<br>`dashboards.permissions:read`<br>`dashboards.permissions:write` | Read, create, update, and delete all dashboards. |
|
||||
| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and <br>`dashboards:write`<br>`dashboards:delete`<br>`dashboards:create`<br>`dashboards.permissions:read`<br>`dashboards.permissions:write` | Read, create, update, and delete all dashboards. |
|
||||
| `fixed:dashboards.insights:reader` | `fixed_JlBJ2_gizP8zhgaeGE2rjyZe2Rs` | `dashboards.insights:read` | Read dashboard insights data and see presence indicators. |
|
||||
| `fixed:dashboards.permissions:reader` | `fixed_f17oxuXW_58LL8mYJsm4T_mCeIw` | `dashboards.permissions:read` | Read all dashboard permissions. |
|
||||
| `fixed:dashboards.permissions:writer` | `fixed_CcznxhWX_Yqn8uWMXMQ-b5iFW9k` | All permissions from `fixed:dashboards.permissions:reader` and <br>`dashboards.permissions:write` | Read and update all dashboard permissions. |
|
||||
|
||||
+1
-5
@@ -197,11 +197,7 @@ However, you can export it by manually copying the content and name of the notif
|
||||
|
||||
All notification policies are provisioned through a single resource: the root of the notification policy tree.
|
||||
|
||||
{{% admonition type="warning" %}}
|
||||
|
||||
Since the policy tree is a single resource, provisioning it overwrites a policy tree created through any other means.
|
||||
|
||||
{{< /admonition >}}
|
||||
{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
To export the notification policy tree from the Grafana UI, complete the following steps.
|
||||
|
||||
|
||||
+1
-5
@@ -702,11 +702,7 @@ Create or reset the notification policy tree using provisioning files in your Gr
|
||||
|
||||
In Grafana, the entire notification policy tree is considered a single, large resource. Add new specific policies as sub-policies under the root policy. Since specific policies may depend on each other, you cannot provision subsets of the policy tree; the entire tree must be defined in a single place.
|
||||
|
||||
{{% admonition type="warning" %}}
|
||||
|
||||
Since the policy tree is a single resource, provisioning it will overwrite a policy tree created through any other means.
|
||||
|
||||
{{< /admonition >}}
|
||||
{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
1. Find the notification policy tree in Grafana.
|
||||
1. [Export](ref:export_policies) and download a provisioning file for your notification policy tree.
|
||||
|
||||
+1
-5
@@ -341,11 +341,7 @@ In this section, we'll create Terraform configurations for each alerting resourc
|
||||
|
||||
[Notification policies](ref:notification-policy) defines how to route alert instances to your contact points.
|
||||
|
||||
{{% admonition type="warning" %}}
|
||||
|
||||
Since the policy tree is a single resource, provisioning the `grafana_notification_policy` resource will overwrite a policy tree created through any other means.
|
||||
|
||||
{{< /admonition >}}
|
||||
{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
1. Find the default notification policy tree. Alternatively, consider writing the resource in code as demonstrated in the example below.
|
||||
|
||||
|
||||
@@ -81,8 +81,6 @@ Grafana enables you to share dashboards and panels with other users within your
|
||||
- Reports
|
||||
- Library panels
|
||||
|
||||
You can also invite new members to your organization from the **Share** menu. For more information, refer to [Invite new members](#invite-new-members).
|
||||
|
||||
You must have an authorized viewer permission to see an image rendered by a direct link. The same permission is also required to view embedded links unless you have anonymous access permission enabled for your Grafana instance.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
@@ -140,7 +138,7 @@ Learn how to configure and manage externally shared dashboards in [Externally sh
|
||||
### Schedule a report
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
This feature is only available in Grafana Enterprise.
|
||||
This feature is only available on Grafana Enterprise.
|
||||
{{< /admonition >}}
|
||||
|
||||
To share your dashboard as a report, follow these steps:
|
||||
@@ -204,6 +202,10 @@ In addition to sharing dashboards as links, reports, and snapshots, you can expo
|
||||
|
||||
### Export a dashboard as PDF
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
This feature is only available on Grafana Enterprise.
|
||||
{{< /admonition >}}
|
||||
|
||||
To export a dashboard in its current state as a PDF, follow these steps:
|
||||
|
||||
1. Click **Dashboards** in the main menu.
|
||||
@@ -365,23 +367,3 @@ To delete existing snapshots, follow these steps:
|
||||
1. Click the red **x** next to the snapshot URL that you want to delete.
|
||||
|
||||
The snapshot is immediately deleted. You may need to clear your browser cache or use a private or incognito browser to confirm this.
|
||||
|
||||
## Invite new members
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
This feature is only available on Grafana Cloud.
|
||||
{{< /admonition >}}
|
||||
|
||||
You can invite new members to your organization using the **Share** drop-down menu. You must have the `OrgUsersAdd` permission to use this feature.
|
||||
|
||||
To invite a new member to your organization, follow these steps:
|
||||
|
||||
1. Click **Dashboards** in the main menu and open any dashboard.
|
||||
1. Click the **Share** drop-down list in the top-right corner and select **Invite new member**.
|
||||
|
||||
The **Members** page of your Grafana Cloud Portal opens.
|
||||
|
||||
1. Enter the email address of the new member in the provided field.
|
||||
1. Make a selection in the **Role** drop-down list.
|
||||
1. (Optional) Select the **Receive billing emails** checkbox, if applicable.
|
||||
1. Click **Invite**.
|
||||
|
||||
@@ -2753,6 +2753,10 @@ Set the default start of the week, valid values are: `saturday`, `sunday`, `mond
|
||||
|
||||
Set this to `false` to disable expressions and hide them in the Grafana UI. Default is `true`.
|
||||
|
||||
#### `sql_expression_cell_limit`
|
||||
|
||||
Set the maximum number of cells that can be passed to a SQL expression. Default is `100000`.
|
||||
|
||||
### `[geomap]`
|
||||
|
||||
This section controls the defaults settings for **Geomap Plugin**.
|
||||
|
||||
@@ -60,7 +60,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
|
||||
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
|
||||
| `lokiQueryHints` | Enables query hints for Loki | Yes |
|
||||
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
|
||||
| `promQLScope` | In-development feature that will allow injection of labels into prometheus queries. | Yes |
|
||||
| `groupToNestedTableTransformation` | Enables the group to nested table transformation | Yes |
|
||||
| `newPDFRendering` | New implementation for the dashboard-to-PDF rendering | Yes |
|
||||
| `tlsMemcached` | Use TLS-enabled memcached in the enterprise caching feature | Yes |
|
||||
@@ -184,7 +183,7 @@ Experimental features might be changed or removed without prior notice.
|
||||
| `kubernetesFeatureToggles` | Use the kubernetes API for feature toggle management in the frontend |
|
||||
| `newFolderPicker` | Enables the nested folder picker without having nested folders enabled |
|
||||
| `scopeApi` | In-development feature flag for the scope api using the app platform. |
|
||||
| `sqlExpressions` | Enables using SQL and DuckDB functions as Expressions. |
|
||||
| `sqlExpressions` | Enables SQL Expressions, which can execute SQL queries against data source results. |
|
||||
| `nodeGraphDotLayout` | Changed the layout algorithm for the node graph |
|
||||
| `kubernetesAggregator` | Enable grafana's embedded kube-aggregator |
|
||||
| `expressionParser` | Enable new expression parser |
|
||||
@@ -228,6 +227,7 @@ Experimental features might be changed or removed without prior notice.
|
||||
| `newLogsPanel` | Enables the new logs panel in Explore |
|
||||
| `pluginsCDNSyncLoader` | Load plugins from CDN synchronously |
|
||||
| `assetSriChecks` | Enables SRI checks for Grafana JavaScript assets |
|
||||
| `extraLanguages` | Enables additional languages |
|
||||
|
||||
## Development feature toggles
|
||||
|
||||
|
||||
+67
-53
@@ -22,23 +22,23 @@ weight: 500
|
||||
# Configure SAML authentication using the configuration file
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
Available in [Grafana Enterprise](../../../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud).
|
||||
Available in [Grafana Enterprise](/docs/grafana/<GRAFANA_VERSION>/introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud).
|
||||
{{% /admonition %}}
|
||||
|
||||
SAML authentication integration allows your Grafana users to log in by using an external SAML 2.0 Identity Provider (IdP). To enable this, Grafana becomes a Service Provider (SP) in the authentication flow, interacting with the IdP to exchange user information.
|
||||
|
||||
You can configure SAML authentication in Grafana through one of the following methods:
|
||||
|
||||
- the Grafana configuration file
|
||||
- the API (refer to [SSO Settings API](../../../../developers/http_api/sso-settings/))
|
||||
- the user interface (refer to [Configure SAML authentication using the Grafana user interface](../saml-ui/))
|
||||
- the Terraform provider (refer to [Terraform docs](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/sso_settings))
|
||||
- The Grafana configuration file
|
||||
- The API (refer to [SSO Settings API](/docs/grafana/<GRAFANA_VERSION>/developers/http_api/sso-settings/)
|
||||
- The user interface (refer to [Configure SAML authentication using the Grafana user interface](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-authentication/saml-ui/)
|
||||
- The Terraform provider (refer to [Terraform docs](https://registry.terraform.io/providers/grafana/grafana/<GRAFANA_VERSION>/docs/resources/sso_settings))
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
The API and Terraform support are available in Public Preview in Grafana v11.1 behind the `ssoSettingsSAML` feature toggle. You must also enable the `ssoSettingsApi` flag.
|
||||
{{% /admonition %}}
|
||||
|
||||
All methods offer the same configuration options, but you might prefer using the Grafana configuration file or the Terraform provider if you want to keep all of Grafana's authentication settings in one place. Grafana Cloud users do not have access to Grafana configuration file, so they should configure SAML through the other methods.
|
||||
All methods offer the same configuration options. However, if you want to keep all of Grafana authentication settings in one place, use the Grafana configuration file or the Terraform provider. If you are a Grafana Cloud user, you do not have access to Grafana configuration file. Instead, configure SAML through the other methods.
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
Configuration in the API takes precedence over the configuration in the Grafana configuration file. SAML settings from the API will override any SAML configuration set in the Grafana configuration file.
|
||||
@@ -46,6 +46,10 @@ Configuration in the API takes precedence over the configuration in the Grafana
|
||||
|
||||
## Supported SAML
|
||||
|
||||
The following indicate what Grafana supports.
|
||||
|
||||
### Bindings
|
||||
|
||||
Grafana supports the following SAML 2.0 bindings:
|
||||
|
||||
- From the Service Provider (SP) to the Identity Provider (IdP):
|
||||
@@ -56,12 +60,13 @@ Grafana supports the following SAML 2.0 bindings:
|
||||
- From the Identity Provider (IdP) to the Service Provider (SP):
|
||||
- `HTTP-POST` binding
|
||||
|
||||
In terms of security:
|
||||
### Security
|
||||
|
||||
- Grafana supports signed and encrypted assertions.
|
||||
- Grafana does not support signed or encrypted requests.
|
||||
Grafana supports signed and encrypted assertions, and does _not_ support encrypted requests.
|
||||
|
||||
In terms of initiation, Grafana supports:
|
||||
### Initiation
|
||||
|
||||
Grafana supports:
|
||||
|
||||
- SP-initiated requests
|
||||
- IdP-initiated requests
|
||||
@@ -71,7 +76,7 @@ By default, SP-initiated requests are enabled. For instructions on how to enable
|
||||
{{% admonition type="note" %}}
|
||||
It is possible to set up Grafana with SAML authentication using Azure AD. However, if an Azure AD user belongs to more than 150 groups, a Graph API endpoint is shared instead.
|
||||
|
||||
Grafana versions 11.1 and below, do not support fetching the groups from the Graph API endpoint. As a result, users with more than 150 groups will not be able to retrieve their groups. Instead, it is recommended that you use OIDC/OAuth workflows,.
|
||||
Grafana versions 11.1 and below, do not support fetching the groups from the Graph API endpoint. As a result, users with more than 150 groups will not be able to retrieve their groups. Instead, it is recommended that you use OIDC/OAuth workflows.
|
||||
|
||||
As of Grafana 11.2, the SAML integration offers a mechanism to retrieve user groups from the Graph API.
|
||||
|
||||
@@ -84,16 +89,16 @@ Related links:
|
||||
|
||||
### Edit SAML options in the Grafana config file
|
||||
|
||||
1. In the `[auth.saml]` section in the Grafana configuration file, set [`enabled`](../../../configure-grafana/enterprise-configuration/#enabled) to `true`.
|
||||
1. Configure the [certificate and private key](#certificate-and-private-key).
|
||||
1. In the `[auth.saml]` section in the Grafana configuration file, set [`enabled`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#enabled-3) to `true`.
|
||||
1. Optionally, configure the [certificate and private key](#certificate-and-private-key").
|
||||
1. On the Okta application page where you have been redirected after application created, navigate to the **Sign On** tab and find **Identity Provider metadata** link in the **Settings** section.
|
||||
1. Set the [`idp_metadata_url`](../../../configure-grafana/enterprise-configuration/#idp_metadata_url) to the URL obtained from the previous step. The URL should look like `https://<your-org-id>.okta.com/app/<application-id>/sso/saml/metadata`.
|
||||
1. Set the [`idp_metadata_url`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#idp_metadata_url) to the URL obtained from the previous step. The URL should look like `https://<your-org-id>.okta.com/app/<application-id>/sso/saml/metadata`.
|
||||
1. Set the following options to the attribute names configured at the **step 10** of the SAML integration setup. You can find this attributes on the **General** tab of the application page (**ATTRIBUTE STATEMENTS** and **GROUP ATTRIBUTE STATEMENTS** in the **SAML Settings** section).
|
||||
- [`assertion_attribute_login`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_login)
|
||||
- [`assertion_attribute_email`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_email)
|
||||
- [`assertion_attribute_name`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_name)
|
||||
- [`assertion_attribute_groups`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_groups)
|
||||
1. (Optional) Set the `name` parameter in the `[auth.saml]` section in the Grafana configuration file. This parameter replaces SAML in the Grafana user interface in locations such as the sign-in button.
|
||||
- [`assertion_attribute_login`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_login)
|
||||
- [`assertion_attribute_email`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_email)
|
||||
- [`assertion_attribute_name`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_name)
|
||||
- [`assertion_attribute_groups`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_groups)
|
||||
1. Optionally, set the `name` parameter in the `[auth.saml]` section in the Grafana configuration file. This parameter replaces SAML in the Grafana user interface in locations such as the sign-in button.
|
||||
1. Save the configuration file and then restart the Grafana server.
|
||||
|
||||
When you are finished, the Grafana configuration might look like this example:
|
||||
@@ -119,7 +124,7 @@ assertion_attribute_groups = Group
|
||||
|
||||
To use the SAML integration, in the `auth.saml` section of in the Grafana custom configuration file, set `enabled` to `true`.
|
||||
|
||||
Refer to [Configuration](../../../configure-grafana/) for more information about configuring Grafana.
|
||||
Refer to [Configuration](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/) for more information about configuring Grafana.
|
||||
|
||||
## Additional configuration for HTTP-Post binding
|
||||
|
||||
@@ -133,9 +138,11 @@ For Grafana Cloud instances, please contact Grafana Support to update the `conte
|
||||
|
||||
## Certificate and private key
|
||||
|
||||
Commonly, the certificate and key are embedded in the [IDP metadata](#configure-the-saml-toolkit-application-endpoints) and refreshed as needed by Grafana automatically. However, if your IdP expects signed requests, you must supply a certificate and private key.
|
||||
|
||||
The SAML SSO standard uses asymmetric encryption to exchange information between the SP (Grafana) and the IdP. To perform such encryption, you need a public part and a private part. In this case, the X.509 certificate provides the public part, while the private key provides the private part. The private key needs to be issued in a [PKCS#8](https://en.wikipedia.org/wiki/PKCS_8) format.
|
||||
|
||||
Grafana supports two ways of specifying both the `certificate` and `private_key`.
|
||||
If you are directly supplying the certificate and key, Grafana supports two ways of specifying both the `certificate` and `private_key`:
|
||||
|
||||
- Without a suffix (`certificate` or `private_key`), the configuration assumes you've supplied the base64-encoded file contents.
|
||||
- With the `_path` suffix (`certificate_path` or `private_key_path`), then Grafana treats the value entered as a file path and attempts to read the file from the file system.
|
||||
@@ -144,9 +151,9 @@ Grafana supports two ways of specifying both the `certificate` and `private_key`
|
||||
You can only use one form of each configuration option. Using multiple forms, such as both `certificate` and `certificate_path`, results in an error.
|
||||
{{% /admonition %}}
|
||||
|
||||
---
|
||||
Always work with your company's security team on setting up certificates and private keys. If you need to generate them yourself (such as in the short term, for testing purposes, and so on), use the following example to generate your certificate and private key, including the step of ensuring that the key is generated with the [PKCS#8](https://en.wikipedia.org/wiki/PKCS_8) format.
|
||||
|
||||
### Generate private key for SAML authentication:
|
||||
### Example of private key generation for SAML authentication
|
||||
|
||||
An example of how to generate a self-signed certificate and private key that's valid for one year:
|
||||
|
||||
@@ -154,7 +161,15 @@ An example of how to generate a self-signed certificate and private key that's v
|
||||
$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
|
||||
```
|
||||
|
||||
The generated `key.pem` and `cert.pem` files are then used for certificate and private_key.
|
||||
Base64-encode the cert.pem and key.pem files:
|
||||
(-w0 switch is not needed on Mac, only for Linux)
|
||||
|
||||
```sh
|
||||
$ base64 -i key.pem -o key.pem.base64
|
||||
$ base64 -i cert.pem -o cert.pem.base64
|
||||
```
|
||||
|
||||
The base64-encoded values (`key.pem.base64, cert.pem.base64` files) are then used for certificate and private key.
|
||||
|
||||
The key you provide should look like:
|
||||
|
||||
@@ -169,16 +184,15 @@ The key you provide should look like:
|
||||
|
||||
Grafana supports user authentication through Azure AD, which is useful when you want users to access Grafana using single sign-on. This topic shows you how to configure SAML authentication in Grafana with [Azure AD](https://azure.microsoft.com/en-us/services/active-directory/).
|
||||
|
||||
**Before you begin:**
|
||||
**Before you begin**
|
||||
|
||||
- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana.
|
||||
- [Roles and permissions](../../../../administration/roles-and-permissions/).
|
||||
- Learn the limitations of Azure AD SAML integration.
|
||||
- [Azure AD SAML limitations](https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim)
|
||||
- Configure SAML integration with Azure AD, create an app integration inside the Azure AD organization first.
|
||||
- [Add app integration in Azure AD](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/add-application-portal-configure)
|
||||
- If you have users that belong to more than 150 groups, you need to configure a registered application to provide an Azure Graph API to retrieve the groups.
|
||||
- [Setup Azure AD Graph API applications](#set-up-saml-with-azure-ad)
|
||||
Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/).
|
||||
|
||||
Learn the [limitations of Azure AD SAML] (https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim) integration.
|
||||
|
||||
Configure SAML integration with Azure AD, [creating an Enterprise Application](#add-microsoft-entra-saml-toolkit-from-the-gallery) inside the Azure AD organization first and then [enable single sign-on](#configure-the-saml-toolkit-application-endpoints).
|
||||
|
||||
If you have users that belong to more than 150 groups, configure a registered application to provide an Azure Graph API to retrieve the groups. Refer to [Setup Azure AD Graph API applications](#configure-a-graph-api-application-in-azure-ad).
|
||||
|
||||
### Generate self-signed certificates
|
||||
|
||||
@@ -277,7 +291,7 @@ Grafana supports user authentication through Okta, which is useful when you want
|
||||
**Before you begin:**
|
||||
|
||||
- To configure SAML integration with Okta, create an app integration inside the Okta organization first. [Add app integration in Okta](https://help.okta.com/en/prod/Content/Topics/Apps/apps-overview-add-apps.htm)
|
||||
- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](../../../../administration/roles-and-permissions/).
|
||||
- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/).
|
||||
|
||||
**To set up SAML with Okta:**
|
||||
|
||||
@@ -391,7 +405,7 @@ Additionally, Grafana did not support IdP sessions and could not include the `Se
|
||||
Starting from Grafana version 11.5, Grafana uses the `NameID` from the SAML assertion to create the logout request. If the `NameID` is not present in the assertion, Grafana defaults to using the user's `Login` attribute. Additionally, Grafana supports including the `SessionIndex` in the logout request if it is provided in the SAML assertion by the IdP.
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
These improvements are available in public preview behind the `improvedExternalSessionHandling` feature toggle, starting from Grafana v11.5. To enable it, refer to the [Configure feature toggles](../../../configure-grafana/feature-toggles/)
|
||||
These improvements are available in public preview behind the `improvedExternalSessionHandlingSAML` feature toggle, starting from Grafana v11.5. To enable it, refer to the [Configure feature toggles](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/)
|
||||
{{% /admonition %}}
|
||||
|
||||
### Assertion mapping
|
||||
@@ -435,11 +449,11 @@ auto_login = true
|
||||
|
||||
Group synchronization allows you to map user groups from an identity provider to Grafana teams and roles.
|
||||
|
||||
To use SAML group synchronization, set [`assertion_attribute_groups`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_groups) to the attribute name where you store user groups.
|
||||
To use SAML group synchronization, set [`assertion_attribute_groups`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_groups) to the attribute name where you store user groups.
|
||||
Then Grafana will use attribute values extracted from SAML assertion to add user to Grafana teams and grant them roles.
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
Team sync allows you sync users from SAML to Grafana teams. It does not automatically create teams in Grafana. You need to create teams in Grafana before you can use this feature.
|
||||
Team sync allows you sync users from SAML to Grafana teams, but you must create teams in Grafana before you can use this feature. It does not automatically create teams in Grafana.
|
||||
{{% /admonition %}}
|
||||
|
||||
Given the following partial SAML assertion:
|
||||
@@ -474,22 +488,22 @@ The following `External Group ID`s would be valid for configuring team sync or r
|
||||
- `admins_group`
|
||||
- `division_1`
|
||||
|
||||
To learn more about how to configure group synchronization, refer to [Configure team sync](../../configure-team-sync/) and [Configure group attribute sync](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-group-attribute-sync) documentation.
|
||||
To learn more about how to configure group synchronization, refer to [Configure team sync](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-group-attribute-sync/) and [Configure group attribute sync](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-security/configure-group-attribute-sync) documentation.
|
||||
|
||||
### Configure role sync
|
||||
|
||||
Role sync allows you to map user roles from an identity provider to Grafana. To enable role sync, configure role attribute and possible values for the Editor, Admin, and Grafana Admin roles. For more information about user roles, refer to [Roles and permissions](../../../../administration/roles-and-permissions/).
|
||||
Role sync allows you to map user roles from an identity provider to Grafana. To enable role sync, configure role attribute and possible values for the Editor, Admin, and Grafana Admin roles. For more information about user roles, refer to [Roles and permissions](/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/).
|
||||
|
||||
1. In the configuration file, set [`assertion_attribute_role`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_role) option to the attribute name where the role information will be extracted from.
|
||||
1. Set the [`role_values_none`](../../../configure-grafana/enterprise-configuration/#role_values_none) option to the values mapped to the `None` role.
|
||||
1. Set the [`role_values_viewer`](../../../configure-grafana/enterprise-configuration/#role_values_viewer) option to the values mapped to the `Viewer` role.
|
||||
1. Set the [`role_values_editor`](../../../configure-grafana/enterprise-configuration/#role_values_editor) option to the values mapped to the `Editor` role.
|
||||
1. Set the [`role_values_admin`](../../../configure-grafana/enterprise-configuration/#role_values_admin) option to the values mapped to the organization `Admin` role.
|
||||
1. Set the [`role_values_grafana_admin`](../../../configure-grafana/enterprise-configuration/#role_values_grafana_admin) option to the values mapped to the `Grafana Admin` role.
|
||||
1. In the configuration file, set [`assertion_attribute_role`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_role) option to the attribute name where the role information will be extracted from.
|
||||
1. Set the [`role_values_none`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#role_values_none) option to the values mapped to the `None` role.
|
||||
1. Set the [`role_values_viewer`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#role_values_viewer) option to the values mapped to the `Viewer` role.
|
||||
1. Set the [`role_values_editor`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#role_values_editor) option to the values mapped to the `Editor` role.
|
||||
1. Set the [`role_values_admin`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#role_values_admin) option to the values mapped to the organization `Admin` role.
|
||||
1. Set the [`role_values_grafana_admin`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#role_values_grafana_admin) option to the values mapped to the `Grafana Admin` role.
|
||||
|
||||
If a user role doesn't match any of configured values, then the role specified by the `auto_assign_org_role` config option will be assigned. If the `auto_assign_org_role` field is not set then the user role will default to `Viewer`.
|
||||
|
||||
For more information about roles and permissions in Grafana, refer to [Roles and permissions](../../../../administration/roles-and-permissions/).
|
||||
For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/).
|
||||
|
||||
Example configuration:
|
||||
|
||||
@@ -518,8 +532,8 @@ skip_org_role_sync = true
|
||||
|
||||
Organization mapping allows you to assign users to particular organization in Grafana depending on attribute value obtained from identity provider.
|
||||
|
||||
1. In configuration file, set [`assertion_attribute_org`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_org) to the attribute name you store organization info in. This attribute can be an array if you want a user to be in multiple organizations.
|
||||
1. Set [`org_mapping`](../../../configure-grafana/enterprise-configuration/#org_mapping) option to the comma-separated list of `Organization:OrgId` pairs to map organization from IdP to Grafana organization specified by ID. If you want users to have different roles in multiple organizations, you can set this option to a comma-separated list of `Organization:OrgId:Role` mappings.
|
||||
1. In configuration file, set [`assertion_attribute_org`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_org) to the attribute name you store organization info in. This attribute can be an array if you want a user to be in multiple organizations.
|
||||
1. Set [`org_mapping`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#org_mapping) option to the comma-separated list of `Organization:OrgId` pairs to map organization from IdP to Grafana organization specified by ID. If you want users to have different roles in multiple organizations, you can set this option to a comma-separated list of `Organization:OrgId:Role` mappings.
|
||||
|
||||
For example, use following configuration to assign users from `Engineering` organization to the Grafana organization with ID `2` as Editor and users from `Sales` - to the org with ID `3` as Admin, based on `Org` assertion attribute value:
|
||||
|
||||
@@ -566,7 +580,7 @@ You can use `*` as the Grafana organization in the mapping if you want all users
|
||||
|
||||
### Configure allowed organizations
|
||||
|
||||
With the [`allowed_organizations`](../../../configure-grafana/enterprise-configuration/#allowed_organizations) option you can specify a list of organizations where the user must be a member of at least one of them to be able to log in to Grafana.
|
||||
With the [`allowed_organizations`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/enterprise-configuration/#allowed_organizations) option you can specify a list of organizations where the user must be a member of at least one of them to be able to log in to Grafana.
|
||||
|
||||
To put values containing spaces in the list, use the following JSON syntax:
|
||||
|
||||
@@ -632,11 +646,11 @@ resource "grafana_sso_settings" "saml_sso_settings" {
|
||||
}
|
||||
```
|
||||
|
||||
Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/sso_settings) for a complete reference on using the `grafana_sso_settings` resource.
|
||||
Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafana/<GRAFANA_VERSION>/docs/resources/sso_settings) for a complete reference on using the `grafana_sso_settings` resource.
|
||||
|
||||
## Troubleshoot SAML authentication in Grafana
|
||||
|
||||
To troubleshoot and get more log information, enable SAML debug logging in the configuration file. Refer to [Configuration](../../../configure-grafana/#filters) for more information.
|
||||
To troubleshoot and get more log information, enable SAML debug logging in the configuration file. Refer to [Configuration](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#filters) for more information.
|
||||
|
||||
```ini
|
||||
[log]
|
||||
@@ -692,7 +706,7 @@ The keys you provide should look like:
|
||||
|
||||
When the user logs in using SAML and gets presented with "origin not allowed", the user might be issuing the login from an IdP (identity provider) service or the user is behind a reverse proxy. This potentially happens as Grafana's CSRF checks deem the requests to be invalid. For more information [CSRF](https://owasp.org/www-community/attacks/csrf).
|
||||
|
||||
To solve this issue, you can configure either the [`csrf_trusted_origins`](../../../configure-grafana/#csrf_trusted_origins) or [`csrf_additional_headers`](../../../configure-grafana/#csrf_additional_headers) option in the SAML configuration.
|
||||
To solve this issue, you can configure either the [`csrf_trusted_origins`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#csrf_trusted_origins) or [`csrf_additional_headers`](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#csrf_additional_headers) option in the SAML configuration.
|
||||
|
||||
Example of a configuration file:
|
||||
|
||||
@@ -735,7 +749,7 @@ Ensure cookie_secure is set to true to ensure that cookies are only sent over HT
|
||||
|
||||
## Configure SAML authentication in Grafana
|
||||
|
||||
The table below describes all SAML configuration options. Continue reading below for details on specific options. Like any other Grafana configuration, you can apply these options as [environment variables](../../../configure-grafana/#override-configuration-with-environment-variables).
|
||||
The table below describes all SAML configuration options. Continue reading below for details on specific options. Like any other Grafana configuration, you can apply these options as [environment variables](/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/#override-configuration-with-environment-variables).
|
||||
|
||||
| Setting | Required | Description | Default |
|
||||
| ---------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- |
|
||||
|
||||
@@ -150,7 +150,7 @@ To install plugins in the Docker container, complete the following steps:
|
||||
|
||||
```bash
|
||||
docker run -d -p 3000:3000 --name=grafana \
|
||||
-e "GF_PLUGINS_PREINSTALL=grafana-clock-panel 1.0.1" \
|
||||
-e "GF_PLUGINS_PREINSTALL=grafana-clock-panel@1.0.1" \
|
||||
grafana/grafana-enterprise
|
||||
```
|
||||
|
||||
|
||||
@@ -1386,6 +1386,8 @@ Status: Conflict
|
||||
|
||||
### <span id="route-put-policy-tree"></span> Sets the notification policy tree. (_RoutePutPolicyTree_)
|
||||
|
||||
{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
```
|
||||
PUT /api/v1/provisioning/policies
|
||||
```
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: 'Warning Provisioning Tree'
|
||||
---
|
||||
|
||||
{{% admonition type="warning" %}}
|
||||
|
||||
Since the policy tree is a single resource, provisioning it will overwrite all policies in the notification policy tree. However, it does not affect internal policies created when alert rules directly select a contact point.
|
||||
|
||||
{{< /admonition >}}
|
||||
@@ -76,7 +76,7 @@ require (
|
||||
github.com/googleapis/go-sql-spanner v1.11.1 // @grafana/grafana-search-and-storage
|
||||
github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group
|
||||
github.com/gorilla/websocket v1.5.3 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 // @grafana/alerting-backend
|
||||
github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e // @grafana/alerting-backend
|
||||
github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa // @grafana/identity-access-team
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 // @grafana/identity-access-team
|
||||
github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics
|
||||
@@ -92,7 +92,7 @@ require (
|
||||
github.com/grafana/grafana-cloud-migration-snapshot v1.6.0 // @grafana/grafana-operator-experience-squad
|
||||
github.com/grafana/grafana-google-sdk-go v0.2.1 // @grafana/partner-datasources
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 // @grafana/grafana-backend-group
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.270.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/loki/v3 v3.2.1 // @grafana/observability-logs
|
||||
github.com/grafana/otel-profiling-go v0.5.1 // @grafana/grafana-backend-group
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // @grafana/observability-traces-and-profiling
|
||||
@@ -160,15 +160,15 @@ require (
|
||||
github.com/yudai/gojsondiff v1.0.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/collector/pdata v1.22.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // @grafana/plugins-platform-backend
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.59.0 // @grafana/grafana-operator-experience-squad
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // @grafana/grafana-operator-experience-squad
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.28.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel v1.34.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel v1.35.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // @grafana/grafana-backend-group
|
||||
go.uber.org/atomic v1.11.0 // @grafana/alerting-backend
|
||||
go.uber.org/goleak v1.3.0 // @grafana/grafana-search-and-storage
|
||||
go.uber.org/zap v1.27.0 // @grafana/identity-access-team
|
||||
@@ -335,7 +335,7 @@ require (
|
||||
github.com/dolthub/maphash v0.1.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.2.0 // indirect
|
||||
github.com/elazarl/goproxy v1.7.1 // indirect
|
||||
github.com/elazarl/goproxy v1.7.2 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/emicklei/proto v1.13.2 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
@@ -523,10 +523,10 @@ require (
|
||||
go.opencensus.io v0.24.0 // @grafana/grafana-backend-group
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.33.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // @grafana/sharing-squad
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // @grafana/sharing-squad
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
|
||||
@@ -1108,8 +1108,8 @@ github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8E
|
||||
github.com/efficientgo/core v1.0.0-rc.3 h1:X6CdgycYWDcbYiJr1H1+lQGzx13o7bq3EUkbB9DsSPc=
|
||||
github.com/efficientgo/core v1.0.0-rc.3/go.mod h1:FfGdkzWarkuzOlY04VY+bGfb1lWrjaL6x/GLcQ4vJps=
|
||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elazarl/goproxy v1.7.1 h1:1P7LPSxbqtNxusFnXclj6O56pjfq1xOQZ6a0mwwKUlY=
|
||||
github.com/elazarl/goproxy v1.7.1/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
@@ -1559,8 +1559,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 h1:71o8Bxw/wg+aBRUASiGux67gDEUC2bqq3I+x2hw8eIc=
|
||||
github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e h1:noJzp/qZGIto4XdZkvj2EKQ1bQeqCRs0bedxdJN17sQ=
|
||||
github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e/go.mod h1:HfvjmU3UqCIpoy9Z2wgKGrZ4A5vz+yQlP9ZXvCfEkiA=
|
||||
github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa h1:08Wh/svkv8WpDuOBBKAzSPa14gKjYLZvQJsHWXLjPuc=
|
||||
github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa/go.mod h1:XVpdLhaeYqz414FmGnW00/0vTe1x8c0GRH3KaeRtyg0=
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 h1:DnRUYiAotHXnrfYJCvhH1NkiyWVcPm5Pd+P7Ugqt/d8=
|
||||
@@ -1593,8 +1593,8 @@ github.com/grafana/grafana-google-sdk-go v0.2.1 h1:XeFdKnkXBjOJjXc1gf4iMx4h5aCHT
|
||||
github.com/grafana/grafana-google-sdk-go v0.2.1/go.mod h1:RiITSHwBhqVTTd3se3HQq5Ncs/wzzhTB9OK5N0J0PEU=
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79 h1:r+mU5bGMzcXCRVAuOrTn54S80qbfVkvTdUJZfSfTNbs=
|
||||
github.com/grafana/grafana-openapi-client-go v0.0.0-20231213163343-bd475d63fb79/go.mod h1:wc6Hbh3K2TgCUSfBC/BOzabItujtHMESZeFk5ZhdxhQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.0 h1:4AcuLEE0UeFG0Eo3P8r1FDS89hgZZ73K550DRz1fgjQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.0/go.mod h1:OuwS4c/JYgn0rr/w5zhJBpLo4gKm/vw15RsfpYAvK9Q=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.270.0 h1:SST2Vo//ITQG5h401gC4jTkJpTHy8OV91sf2uDh6M/8=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.270.0/go.mod h1:Z0Cvkj4WGadz6F6FQmK4NGb/hD18kTTNkSqFb97Rfyc=
|
||||
github.com/grafana/grafana/apps/advisor v0.0.0-20250220163425-b4c4b9abbdc8 h1:mG/6nDlEBVxWlo2GQJVASzucw3ByPIBsec06XcPrjgQ=
|
||||
github.com/grafana/grafana/apps/advisor v0.0.0-20250220163425-b4c4b9abbdc8/go.mod h1:9I1dKV3Dqr0NPR9Af0WJGxOytp5/6W3JLiNChOz8r+c=
|
||||
github.com/grafana/grafana/apps/alerting/notifications v0.0.0-20250220163425-b4c4b9abbdc8 h1:w42GlvkmHG4nM/p1kb2nKmROVP+AHtL3qWEYMhnhCVM=
|
||||
@@ -2522,11 +2522,11 @@ go.opentelemetry.io/contrib/detectors/gcp v1.33.0/go.mod h1:ZHrLmr4ikK2AwRj9QL+c
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.55.0/go.mod h1:rsg1EO8LXSs2po50PB5CeY/MSVlhghuKBgXlKnqm6ks=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.59.0 h1:iQZYNQ7WwIcYXzOPR46FQv9O0dS1PW16RjvR0TjDOe8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.59.0/go.mod h1:54CaSNqYEXvpzDh8KPjiMVoWm60t5R0dZRt0leEPgAs=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 h1:0tY123n7CdWMem7MOVdKOt0YfshufLCwfE5Bob+hQuM=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0/go.mod h1:DQAwmETtZV00skUwgD6+0U89g80NKsJE3DCKeLLPQMI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0 h1:D3htJISCUU/wOVlKwisVKancWm+2U4h9xDEaiMkiyRE=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0/go.mod h1:DAX1bsj+uDm2ZuOQH/RgZRx7RQZWyzV5W2WR/0UX8JA=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.28.0 h1:Xx1N6cDr8iWy1Cz6OcY7oS0ACdt/6HDYTdu4KskuC7s=
|
||||
@@ -2534,8 +2534,8 @@ go.opentelemetry.io/contrib/samplers/jaegerremote v0.28.0/go.mod h1:iWS+NvC948Fy
|
||||
go.opentelemetry.io/otel v1.17.0/go.mod h1:I2vmBGtFaODIVMBSTPVDlJSzBDNf93k60E6Ft0nyjo0=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||
@@ -2549,19 +2549,19 @@ go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.29.0/go.mod h1:BLbf7zb
|
||||
go.opentelemetry.io/otel/metric v1.17.0/go.mod h1:h4skoxdZI17AxwITdmdZjjYJQH5nzijUUjm+wtPph5o=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.17.0/go.mod h1:U87sE0f5vQB7hwUoW98pW5Rz4ZDuCFBZFNUBlSgmDFQ=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.17.0/go.mod h1:I/4vKTgFclIsXRVucpH25X0mpFSczM7aHeaz0ZBLWjY=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
|
||||
@@ -1436,6 +1436,7 @@ go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv+
|
||||
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.29.0/go.mod h1:6zZLdCl2fkauYoZIOn/soQIDSWFmNSRcICarHfuhNJQ=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
||||
|
||||
+4
-4
@@ -223,7 +223,6 @@
|
||||
"postcss-reporter": "7.1.0",
|
||||
"postcss-scss": "4.0.9",
|
||||
"prettier": "3.4.2",
|
||||
"pseudoizer": "^0.1.0",
|
||||
"react-refresh": "0.14.0",
|
||||
"react-select-event": "5.5.1",
|
||||
"redux-mock-store": "1.5.5",
|
||||
@@ -278,8 +277,8 @@
|
||||
"@grafana/prometheus": "workspace:*",
|
||||
"@grafana/runtime": "workspace:*",
|
||||
"@grafana/saga-icons": "workspace:*",
|
||||
"@grafana/scenes": "6.2.1",
|
||||
"@grafana/scenes-react": "6.2.1",
|
||||
"@grafana/scenes": "6.3.1",
|
||||
"@grafana/scenes-react": "6.3.1",
|
||||
"@grafana/schema": "workspace:*",
|
||||
"@grafana/sql": "workspace:*",
|
||||
"@grafana/ui": "workspace:*",
|
||||
@@ -336,6 +335,7 @@
|
||||
"history": "4.10.1",
|
||||
"i18next": "^24.0.0",
|
||||
"i18next-browser-languagedetector": "^8.0.0",
|
||||
"i18next-pseudo": "^2.2.1",
|
||||
"immer": "10.1.1",
|
||||
"immutable": "5.0.3",
|
||||
"ix": "^7.0.0",
|
||||
@@ -365,7 +365,7 @@
|
||||
"ol": "7.4.0",
|
||||
"ol-ext": "4.0.26",
|
||||
"pluralize": "^8.0.0",
|
||||
"prismjs": "1.29.0",
|
||||
"prismjs": "1.30.0",
|
||||
"rc-slider": "11.1.8",
|
||||
"rc-tree": "5.13.0",
|
||||
"re-resizable": "6.10.3",
|
||||
|
||||
@@ -43,9 +43,6 @@ export interface ThemeComponents {
|
||||
sidemenu: {
|
||||
width: number;
|
||||
};
|
||||
menuTabs: {
|
||||
height: number;
|
||||
};
|
||||
horizontalDrawer: {
|
||||
defaultHeight: number;
|
||||
};
|
||||
@@ -96,6 +93,7 @@ export function createComponents(colors: ThemeColors, shadows: ThemeShadows): Th
|
||||
sidemenu: {
|
||||
width: 57,
|
||||
},
|
||||
// @ts-expect-error (added here to not crash plugins that might use it)
|
||||
menuTabs: {
|
||||
height: 5,
|
||||
},
|
||||
|
||||
@@ -61,9 +61,10 @@ const desertBloomTheme: NewThemeOptions = {
|
||||
disabledBackground: 'rgba(168, 156, 134, 0.06)',
|
||||
disabledOpacity: 0.38,
|
||||
},
|
||||
|
||||
gradients: {
|
||||
brandHorizontal: 'linear-gradient(270deg, #FF6F61 0%, #ece0d1 100%)',
|
||||
brandVertical: 'linear-gradient(0.01deg, #FF6F61 0.01%, #ece0d1 99.99%)',
|
||||
brandHorizontal: 'linear-gradient(270deg,rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)',
|
||||
brandVertical: 'linear-gradient(0deg, rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)',
|
||||
},
|
||||
contrastThreshold: 3,
|
||||
hoverFactor: 0.03,
|
||||
|
||||
@@ -284,4 +284,5 @@ export interface AuthSettings {
|
||||
disableLogin?: boolean;
|
||||
passwordlessEnabled?: boolean;
|
||||
basicAuthStrongPasswordPolicy?: boolean;
|
||||
disableSignoutMenu?: boolean;
|
||||
}
|
||||
|
||||
@@ -258,4 +258,5 @@ export interface FeatureToggles {
|
||||
alertRuleRestore?: boolean;
|
||||
grafanaManagedRecordingRulesDatasources?: boolean;
|
||||
inviteUserExperimental?: boolean;
|
||||
extraLanguages?: boolean;
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
"moment-timezone": "0.5.47",
|
||||
"monaco-promql": "1.7.4",
|
||||
"pluralize": "8.0.0",
|
||||
"prismjs": "1.29.0",
|
||||
"prismjs": "1.30.0",
|
||||
"react-highlight-words": "0.21.0",
|
||||
"react-use": "17.6.0",
|
||||
"react-window": "1.8.11",
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file was generated by grafana-app-sdk. DO NOT EDIT.
|
||||
*/
|
||||
import { Spec } from './types.spec.gen';
|
||||
import { Status } from './types.status.gen';
|
||||
|
||||
export interface Metadata {
|
||||
name: string;
|
||||
namespace: string;
|
||||
generateName?: string;
|
||||
selfLink?: string;
|
||||
uid?: string;
|
||||
resourceVersion?: string;
|
||||
generation?: number;
|
||||
creationTimestamp?: string;
|
||||
deletionTimestamp?: string;
|
||||
deletionGracePeriodSeconds?: number;
|
||||
labels?: Record<string, string>;
|
||||
annotations?: Record<string, string>;
|
||||
ownerReferences?: OwnerReference[];
|
||||
finalizers?: string[];
|
||||
managedFields?: ManagedFieldsEntry[];
|
||||
}
|
||||
|
||||
export interface OwnerReference {
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
name: string;
|
||||
uid: string;
|
||||
controller?: boolean;
|
||||
blockOwnerDeletion?: boolean;
|
||||
}
|
||||
|
||||
export interface ManagedFieldsEntry {
|
||||
manager?: string;
|
||||
operation?: string;
|
||||
apiVersion?: string;
|
||||
time?: string;
|
||||
fieldsType?: string;
|
||||
subresource?: string;
|
||||
}
|
||||
|
||||
export interface Dashboard {
|
||||
kind: string;
|
||||
apiVersion: string;
|
||||
metadata: Metadata;
|
||||
spec: Spec;
|
||||
status: Status;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
// metadata contains embedded CommonMetadata and can be extended with custom string fields
|
||||
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
|
||||
// without external reference as using the CommonMetadata reference breaks thema codegen.
|
||||
export interface Metadata {
|
||||
updateTimestamp: string;
|
||||
createdBy: string;
|
||||
uid: string;
|
||||
creationTimestamp: string;
|
||||
deletionTimestamp?: string;
|
||||
finalizers: string[];
|
||||
resourceVersion: string;
|
||||
generation: number;
|
||||
updatedBy: string;
|
||||
labels: Record<string, string>;
|
||||
}
|
||||
|
||||
export const defaultMetadata = (): Metadata => ({
|
||||
updateTimestamp: "",
|
||||
createdBy: "",
|
||||
uid: "",
|
||||
creationTimestamp: "",
|
||||
finalizers: [],
|
||||
resourceVersion: "",
|
||||
generation: 0,
|
||||
updatedBy: "",
|
||||
labels: {},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
export interface Spec {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export const defaultSpec = (): Spec => ({});
|
||||
@@ -0,0 +1,30 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
// ConversionStatus is the status of the conversion of the dashboard.
|
||||
export interface ConversionStatus {
|
||||
// Whether from another version has failed.
|
||||
// If true, means that the dashboard is not valid,
|
||||
// and the caller should instead fetch the stored version.
|
||||
failed: boolean;
|
||||
// The version which was stored when the dashboard was created / updated.
|
||||
// Fetching this version should always succeed.
|
||||
storedVersion: string;
|
||||
// The error message from the conversion.
|
||||
// Empty if the conversion has not failed.
|
||||
error: string;
|
||||
}
|
||||
|
||||
export const defaultConversionStatus = (): ConversionStatus => ({
|
||||
failed: false,
|
||||
storedVersion: "",
|
||||
error: "",
|
||||
});
|
||||
|
||||
export interface Status {
|
||||
// Optional conversion status.
|
||||
conversion?: ConversionStatus;
|
||||
}
|
||||
|
||||
export const defaultStatus = (): Status => ({
|
||||
});
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file was generated by grafana-app-sdk. DO NOT EDIT.
|
||||
*/
|
||||
import { Spec } from './types.spec.gen';
|
||||
import { Status } from './types.status.gen';
|
||||
|
||||
export interface Metadata {
|
||||
name: string;
|
||||
namespace: string;
|
||||
generateName?: string;
|
||||
selfLink?: string;
|
||||
uid?: string;
|
||||
resourceVersion?: string;
|
||||
generation?: number;
|
||||
creationTimestamp?: string;
|
||||
deletionTimestamp?: string;
|
||||
deletionGracePeriodSeconds?: number;
|
||||
labels?: Record<string, string>;
|
||||
annotations?: Record<string, string>;
|
||||
ownerReferences?: OwnerReference[];
|
||||
finalizers?: string[];
|
||||
managedFields?: ManagedFieldsEntry[];
|
||||
}
|
||||
|
||||
export interface OwnerReference {
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
name: string;
|
||||
uid: string;
|
||||
controller?: boolean;
|
||||
blockOwnerDeletion?: boolean;
|
||||
}
|
||||
|
||||
export interface ManagedFieldsEntry {
|
||||
manager?: string;
|
||||
operation?: string;
|
||||
apiVersion?: string;
|
||||
time?: string;
|
||||
fieldsType?: string;
|
||||
subresource?: string;
|
||||
}
|
||||
|
||||
export interface Dashboard {
|
||||
kind: string;
|
||||
apiVersion: string;
|
||||
metadata: Metadata;
|
||||
spec: Spec;
|
||||
status: Status;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
// metadata contains embedded CommonMetadata and can be extended with custom string fields
|
||||
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
|
||||
// without external reference as using the CommonMetadata reference breaks thema codegen.
|
||||
export interface Metadata {
|
||||
updateTimestamp: string;
|
||||
createdBy: string;
|
||||
uid: string;
|
||||
creationTimestamp: string;
|
||||
deletionTimestamp?: string;
|
||||
finalizers: string[];
|
||||
resourceVersion: string;
|
||||
generation: number;
|
||||
updatedBy: string;
|
||||
labels: Record<string, string>;
|
||||
}
|
||||
|
||||
export const defaultMetadata = (): Metadata => ({
|
||||
updateTimestamp: "",
|
||||
createdBy: "",
|
||||
uid: "",
|
||||
creationTimestamp: "",
|
||||
finalizers: [],
|
||||
resourceVersion: "",
|
||||
generation: 0,
|
||||
updatedBy: "",
|
||||
labels: {},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
export interface Spec {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export const defaultSpec = (): Spec => ({});
|
||||
@@ -0,0 +1,30 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
// ConversionStatus is the status of the conversion of the dashboard.
|
||||
export interface ConversionStatus {
|
||||
// Whether from another version has failed.
|
||||
// If true, means that the dashboard is not valid,
|
||||
// and the caller should instead fetch the stored version.
|
||||
failed: boolean;
|
||||
// The version which was stored when the dashboard was created / updated.
|
||||
// Fetching this version should always succeed.
|
||||
storedVersion: string;
|
||||
// The error message from the conversion.
|
||||
// Empty if the conversion has not failed.
|
||||
error: string;
|
||||
}
|
||||
|
||||
export const defaultConversionStatus = (): ConversionStatus => ({
|
||||
failed: false,
|
||||
storedVersion: "",
|
||||
error: "",
|
||||
});
|
||||
|
||||
export interface Status {
|
||||
// Optional conversion status.
|
||||
conversion?: ConversionStatus;
|
||||
}
|
||||
|
||||
export const defaultStatus = (): Status => ({
|
||||
});
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file was generated by grafana-app-sdk. DO NOT EDIT.
|
||||
*/
|
||||
import { Spec } from './types.spec.gen';
|
||||
import { Status } from './types.status.gen';
|
||||
|
||||
export interface Metadata {
|
||||
name: string;
|
||||
namespace: string;
|
||||
generateName?: string;
|
||||
selfLink?: string;
|
||||
uid?: string;
|
||||
resourceVersion?: string;
|
||||
generation?: number;
|
||||
creationTimestamp?: string;
|
||||
deletionTimestamp?: string;
|
||||
deletionGracePeriodSeconds?: number;
|
||||
labels?: Record<string, string>;
|
||||
annotations?: Record<string, string>;
|
||||
ownerReferences?: OwnerReference[];
|
||||
finalizers?: string[];
|
||||
managedFields?: ManagedFieldsEntry[];
|
||||
}
|
||||
|
||||
export interface OwnerReference {
|
||||
apiVersion: string;
|
||||
kind: string;
|
||||
name: string;
|
||||
uid: string;
|
||||
controller?: boolean;
|
||||
blockOwnerDeletion?: boolean;
|
||||
}
|
||||
|
||||
export interface ManagedFieldsEntry {
|
||||
manager?: string;
|
||||
operation?: string;
|
||||
apiVersion?: string;
|
||||
time?: string;
|
||||
fieldsType?: string;
|
||||
subresource?: string;
|
||||
}
|
||||
|
||||
export interface Dashboard {
|
||||
kind: string;
|
||||
apiVersion: string;
|
||||
metadata: Metadata;
|
||||
spec: Spec;
|
||||
status: Status;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
// metadata contains embedded CommonMetadata and can be extended with custom string fields
|
||||
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
|
||||
// without external reference as using the CommonMetadata reference breaks thema codegen.
|
||||
export interface Metadata {
|
||||
updateTimestamp: string;
|
||||
createdBy: string;
|
||||
uid: string;
|
||||
creationTimestamp: string;
|
||||
deletionTimestamp?: string;
|
||||
finalizers: string[];
|
||||
resourceVersion: string;
|
||||
generation: number;
|
||||
updatedBy: string;
|
||||
labels: Record<string, string>;
|
||||
}
|
||||
|
||||
export const defaultMetadata = (): Metadata => ({
|
||||
updateTimestamp: "",
|
||||
createdBy: "",
|
||||
uid: "",
|
||||
creationTimestamp: "",
|
||||
finalizers: [],
|
||||
resourceVersion: "",
|
||||
generation: 0,
|
||||
updatedBy: "",
|
||||
labels: {},
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
// ConversionStatus is the status of the conversion of the dashboard.
|
||||
export interface ConversionStatus {
|
||||
// Whether from another version has failed.
|
||||
// If true, means that the dashboard is not valid,
|
||||
// and the caller should instead fetch the stored version.
|
||||
failed: boolean;
|
||||
// The version which was stored when the dashboard was created / updated.
|
||||
// Fetching this version should always succeed.
|
||||
storedVersion: string;
|
||||
// The error message from the conversion.
|
||||
// Empty if the conversion has not failed.
|
||||
error: string;
|
||||
}
|
||||
|
||||
export const defaultConversionStatus = (): ConversionStatus => ({
|
||||
failed: false,
|
||||
storedVersion: "",
|
||||
error: "",
|
||||
});
|
||||
|
||||
export interface Status {
|
||||
// Optional conversion status.
|
||||
conversion?: ConversionStatus;
|
||||
}
|
||||
|
||||
export const defaultStatus = (): Status => ({
|
||||
});
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
"moment": "2.30.1",
|
||||
"monaco-editor": "0.34.1",
|
||||
"ol": "7.4.0",
|
||||
"prismjs": "1.29.0",
|
||||
"prismjs": "1.30.0",
|
||||
"rc-cascader": "3.33.0",
|
||||
"rc-drawer": "7.2.0",
|
||||
"rc-picker": "4.9.2",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { StoryFn, Meta } from '@storybook/react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Combobox } from '../Combobox/Combobox';
|
||||
import { Checkbox } from '../Forms/Checkbox';
|
||||
import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Select } from '../Select/Select';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { TextArea } from '../TextArea/TextArea';
|
||||
|
||||
@@ -97,11 +97,12 @@ Basic.args = {
|
||||
};
|
||||
|
||||
export const AllComponents: StoryFn = (args) => {
|
||||
const [selected, setSelected] = useState('');
|
||||
const [checkBoxTest, setCheckBoxTest] = useState(false);
|
||||
const [textAreaValue, setTextAreaValue] = useState('');
|
||||
const [inputTextValue, setInputTextValue] = useState('');
|
||||
const [switchTest, setSwitchTest] = useState(false);
|
||||
const [comoboboxValue, setComboboxValue] = useState('');
|
||||
const [radioButtonValue, setRadioButtonValue] = useState('');
|
||||
const [checkBoxValue, setCheckBoxValue] = useState(false);
|
||||
const [textAreaValue, setTextAreaValue] = useState('');
|
||||
const [switchValue, setSwitchValue] = useState(false);
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -117,13 +118,14 @@ export const AllComponents: StoryFn = (args) => {
|
||||
/>
|
||||
)}
|
||||
</AutoSaveField>
|
||||
<AutoSaveField onFinishChange={args.inputSuccessful ? getSuccess : getError} label="Select as child" {...args}>
|
||||
<AutoSaveField onFinishChange={args.inputSuccessful ? getSuccess : getError} label="Combobox as child" {...args}>
|
||||
{(onChange) => (
|
||||
<Select
|
||||
<Combobox
|
||||
options={themeOptions}
|
||||
value={args.weekPickerValue}
|
||||
value={comoboboxValue}
|
||||
onChange={(v) => {
|
||||
onChange(v.value);
|
||||
setComboboxValue(v.value);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@@ -136,9 +138,9 @@ export const AllComponents: StoryFn = (args) => {
|
||||
{(onChange) => (
|
||||
<RadioButtonGroup
|
||||
options={themeOptions}
|
||||
value={selected}
|
||||
value={radioButtonValue}
|
||||
onChange={(themeOption) => {
|
||||
setSelected(themeOption);
|
||||
setRadioButtonValue(themeOption);
|
||||
onChange(themeOption);
|
||||
}}
|
||||
/>
|
||||
@@ -154,11 +156,11 @@ export const AllComponents: StoryFn = (args) => {
|
||||
label="Checkbox test"
|
||||
description="This is a checkbox input"
|
||||
name="checkbox-test"
|
||||
value={checkBoxTest}
|
||||
value={checkBoxValue}
|
||||
onChange={(e) => {
|
||||
const value = e.currentTarget.checked;
|
||||
onChange(value);
|
||||
setCheckBoxTest(value);
|
||||
setCheckBoxValue(value);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@@ -188,10 +190,10 @@ export const AllComponents: StoryFn = (args) => {
|
||||
<Switch
|
||||
label="Switch test"
|
||||
name="switch-test"
|
||||
value={switchTest}
|
||||
value={switchValue}
|
||||
onChange={(e) => {
|
||||
onChange(e.currentTarget.checked);
|
||||
setSwitchTest(e.currentTarget.checked);
|
||||
setSwitchValue(e.currentTarget.checked);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { Combobox } from '../Combobox/Combobox';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
import { Field } from './Field';
|
||||
|
||||
@@ -27,9 +27,13 @@ describe('Field', () => {
|
||||
});
|
||||
|
||||
it('renders with the inputId of its children', () => {
|
||||
const comboboxOptions = [
|
||||
{ label: 'Option 1', value: 'option-1' },
|
||||
{ label: 'Option 2', value: 'option-2' },
|
||||
];
|
||||
render(
|
||||
<Field label="My other label">
|
||||
<Select inputId="my-select-input" onChange={() => {}} />
|
||||
<Combobox id="my-select-input" options={comboboxOptions} onChange={() => {}} />
|
||||
</Field>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { Meta, StoryFn } from '@storybook/react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { Combobox } from '../Combobox/Combobox';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
import { InlineField } from './InlineField';
|
||||
import mdx from './InlineField.mdx';
|
||||
@@ -75,24 +75,22 @@ grow.args = {
|
||||
grow: true,
|
||||
};
|
||||
|
||||
export const withSelect: StoryFn<typeof InlineField> = (args) => {
|
||||
export const withCombobox: StoryFn<typeof InlineField> = (args) => {
|
||||
const comboboxOptions = [
|
||||
{ value: 1, label: 'One' },
|
||||
{ value: 2, label: 'Two' },
|
||||
];
|
||||
const [selected, setSelected] = useState(1);
|
||||
return (
|
||||
<InlineField {...args}>
|
||||
<Select
|
||||
width={16}
|
||||
onChange={action('item selected')}
|
||||
options={[
|
||||
{ value: 1, label: 'One' },
|
||||
{ value: 2, label: 'Two' },
|
||||
]}
|
||||
/>
|
||||
<Combobox width={16} onChange={(v) => setSelected(v.value)} options={comboboxOptions} value={selected} />
|
||||
</InlineField>
|
||||
);
|
||||
};
|
||||
|
||||
withSelect.args = {
|
||||
withCombobox.args = {
|
||||
...basic.args,
|
||||
label: 'Select option',
|
||||
label: 'Combobox option',
|
||||
};
|
||||
|
||||
export const multiple: StoryFn<typeof InlineField> = () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { Combobox } from '../Combobox/Combobox';
|
||||
import { Input } from '../Input/Input';
|
||||
import { Select } from '../Select/Select';
|
||||
|
||||
import { InlineField } from './InlineField';
|
||||
|
||||
@@ -27,9 +27,13 @@ describe('InlineField', () => {
|
||||
});
|
||||
|
||||
it('renders with the inputId of its children', () => {
|
||||
const comboboxOptions = [
|
||||
{ label: 'Option 1', value: '1' },
|
||||
{ label: 'Option 2', value: '2' },
|
||||
];
|
||||
render(
|
||||
<InlineField label="My other label">
|
||||
<Select inputId="my-select-input" onChange={() => {}} />
|
||||
<Combobox id="my-select-input" options={comboboxOptions} onChange={() => {}} />
|
||||
</InlineField>
|
||||
);
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { StringSelector, selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useStyles2 } from '../../../themes';
|
||||
import { getFocusStyles, getMouseFocusStyles } from '../../../themes/mixins';
|
||||
import { getFocusStyles, getInternalRadius, getMouseFocusStyles } from '../../../themes/mixins';
|
||||
import { Tooltip } from '../../Tooltip/Tooltip';
|
||||
import { getPropertiesForButtonSize } from '../commonStyles';
|
||||
|
||||
export const RADIO_GROUP_PADDING = 2;
|
||||
export type RadioButtonSize = 'sm' | 'md';
|
||||
|
||||
export interface RadioButtonProps {
|
||||
@@ -130,7 +131,7 @@ const getRadioButtonStyles = (theme: GrafanaTheme2, size: RadioButtonSize, fullW
|
||||
lineHeight: `${labelHeight}px`,
|
||||
color: textColor,
|
||||
padding: theme.spacing(0, padding),
|
||||
borderRadius: theme.shape.radius.default,
|
||||
borderRadius: getInternalRadius(theme, RADIO_GROUP_PADDING),
|
||||
background: theme.colors.background.primary,
|
||||
cursor: 'pointer',
|
||||
userSelect: 'none',
|
||||
|
||||
@@ -7,8 +7,7 @@ import { GrafanaTheme2, SelectableValue, toIconName } from '@grafana/data';
|
||||
import { useStyles2 } from '../../../themes';
|
||||
import { Icon } from '../../Icon/Icon';
|
||||
|
||||
import { RadioButtonSize, RadioButton } from './RadioButton';
|
||||
|
||||
import { RadioButtonSize, RadioButton, RADIO_GROUP_PADDING } from './RadioButton';
|
||||
export interface RadioButtonGroupProps<T> {
|
||||
value?: T;
|
||||
id?: string;
|
||||
@@ -119,7 +118,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
flexWrap: 'nowrap',
|
||||
border: `1px solid ${theme.components.input.borderColor}`,
|
||||
borderRadius: theme.shape.radius.default,
|
||||
padding: '2px',
|
||||
padding: RADIO_GROUP_PADDING,
|
||||
'&:hover': {
|
||||
borderColor: theme.components.input.borderHover,
|
||||
},
|
||||
|
||||
@@ -6,8 +6,9 @@ import { SelectableValue, GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { IconButton } from '../../components/IconButton/IconButton';
|
||||
import { TabsBar, Tab, TabContent } from '../../components/Tabs';
|
||||
import { useStyles2, useTheme2 } from '../../themes';
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { IconName } from '../../types/icon';
|
||||
import { Box } from '../Layout/Box/Box';
|
||||
import { ScrollContainer } from '../ScrollContainer/ScrollContainer';
|
||||
|
||||
export interface TabConfig {
|
||||
@@ -28,14 +29,11 @@ export interface TabbedContainerProps {
|
||||
export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, testId }: TabbedContainerProps) {
|
||||
const [activeTab, setActiveTab] = useState(tabs.some((tab) => tab.value === defaultTab) ? defaultTab : tabs[0].value);
|
||||
const styles = useStyles2(getStyles);
|
||||
const theme = useTheme2();
|
||||
|
||||
const onSelectTab = (item: SelectableValue<string>) => {
|
||||
setActiveTab(item.value!);
|
||||
};
|
||||
|
||||
const autoHeight = `calc(100% - (${theme.spacing(theme.components.menuTabs.height)} + ${theme.spacing(1)}))`;
|
||||
|
||||
return (
|
||||
<div className={styles.container} data-testid={testId}>
|
||||
<TabsBar className={styles.tabs}>
|
||||
@@ -48,9 +46,11 @@ export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, t
|
||||
icon={t.icon}
|
||||
/>
|
||||
))}
|
||||
<IconButton className={styles.close} onClick={onClose} name="times" tooltip={closeIconTooltip ?? 'Close'} />
|
||||
<Box grow={1} display="flex" justifyContent="flex-end" paddingRight={1}>
|
||||
<IconButton size="lg" onClick={onClose} name="times" tooltip={closeIconTooltip ?? 'Close'} />
|
||||
</Box>
|
||||
</TabsBar>
|
||||
<ScrollContainer height={autoHeight}>
|
||||
<ScrollContainer>
|
||||
<TabContent className={styles.tabContent}>{tabs.find((t) => t.value === activeTab)?.content}</TabContent>
|
||||
</ScrollContainer>
|
||||
</div>
|
||||
@@ -60,21 +60,17 @@ export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, t
|
||||
const getStyles = (theme: GrafanaTheme2) => ({
|
||||
container: css({
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
flex: '1 1 0',
|
||||
minHeight: 0,
|
||||
}),
|
||||
tabContent: css({
|
||||
padding: theme.spacing(2),
|
||||
backgroundColor: theme.colors.background.primary,
|
||||
height: `100%`,
|
||||
}),
|
||||
close: css({
|
||||
position: 'absolute',
|
||||
right: '16px',
|
||||
top: '5px',
|
||||
cursor: 'pointer',
|
||||
fontSize: theme.typography.size.lg,
|
||||
}),
|
||||
tabs: css({
|
||||
paddingTop: theme.spacing(1),
|
||||
paddingTop: theme.spacing(0.5),
|
||||
borderColor: theme.colors.border.weak,
|
||||
ul: {
|
||||
marginLeft: theme.spacing(2),
|
||||
|
||||
@@ -92,11 +92,11 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
whiteSpace: 'nowrap',
|
||||
padding: theme.spacing(0.5),
|
||||
padding: theme.spacing(0, 0.5),
|
||||
}),
|
||||
link: css({
|
||||
color: theme.colors.text.secondary,
|
||||
padding: theme.spacing(1, 1.5, 0.5),
|
||||
padding: theme.spacing(1, 1.5, 1),
|
||||
borderRadius: theme.shape.radius.default,
|
||||
|
||||
display: 'block',
|
||||
@@ -114,7 +114,7 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
position: 'absolute',
|
||||
left: 0,
|
||||
right: 0,
|
||||
height: '4px',
|
||||
height: '2px',
|
||||
borderRadius: theme.shape.radius.default,
|
||||
bottom: 0,
|
||||
},
|
||||
|
||||
@@ -36,8 +36,7 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
tabs: css({
|
||||
position: 'relative',
|
||||
display: 'flex',
|
||||
height: theme.spacing(theme.components.menuTabs.height),
|
||||
alignItems: 'stretch',
|
||||
alignItems: 'center',
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Meta, StoryFn } from '@storybook/react';
|
||||
|
||||
import { BorderRadiusContainer } from './BorderRadius';
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'Docs Overview/Theme',
|
||||
component: BorderRadiusContainer,
|
||||
decorators: [],
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
},
|
||||
args: {
|
||||
referenceBorderRadius: 20,
|
||||
referenceBorderWidth: 10,
|
||||
offset: 0,
|
||||
borderWidth: 2,
|
||||
},
|
||||
argTypes: {
|
||||
offset: {
|
||||
control: {
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
referenceBorderRadius: {
|
||||
control: {
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
referenceBorderWidth: {
|
||||
control: {
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
borderWidth: {
|
||||
control: {
|
||||
min: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const OffsetBorderRadius: StoryFn<typeof BorderRadiusContainer> = (args) => {
|
||||
return <BorderRadiusContainer {...args} />;
|
||||
};
|
||||
|
||||
export default meta;
|
||||
@@ -0,0 +1,87 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { getInternalRadius, getExternalRadius } from '../../themes/mixins';
|
||||
import { Stack } from '../Layout/Stack/Stack';
|
||||
import { Text } from '../Text/Text';
|
||||
|
||||
interface DemoBoxProps {
|
||||
referenceBorderRadius: number;
|
||||
referenceBorderWidth: number;
|
||||
offset: number;
|
||||
borderWidth: number;
|
||||
}
|
||||
|
||||
export const BorderRadiusContainer = ({
|
||||
referenceBorderRadius,
|
||||
referenceBorderWidth,
|
||||
offset,
|
||||
borderWidth,
|
||||
}: DemoBoxProps) => {
|
||||
const styles = useStyles2(getStyles, referenceBorderRadius, referenceBorderWidth, offset, borderWidth);
|
||||
return (
|
||||
<Stack direction="column" alignItems="center" gap={4}>
|
||||
<Stack alignItems="center">
|
||||
{/* eslint-disable-next-line @grafana/no-untranslated-strings */}
|
||||
<Text variant="code">getInternalRadius</Text>
|
||||
<div className={styles.baseForInternal}>
|
||||
<div className={styles.internalContainer} />
|
||||
</div>
|
||||
</Stack>
|
||||
<Stack alignItems="center">
|
||||
{/* eslint-disable-next-line @grafana/no-untranslated-strings */}
|
||||
<Text variant="code">getExternalRadius</Text>
|
||||
<div className={styles.externalContainer}>
|
||||
<div className={styles.baseForExternal} />
|
||||
</div>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
const getStyles = (
|
||||
theme: GrafanaTheme2,
|
||||
referenceBorderRadius: number,
|
||||
referenceBorderWidth: number,
|
||||
offset: number,
|
||||
borderWidth: number
|
||||
) => ({
|
||||
baseForInternal: css({
|
||||
backgroundColor: theme.colors.action.disabledBackground,
|
||||
border: `${referenceBorderWidth}px dashed ${theme.colors.action.disabledText}`,
|
||||
borderRadius: referenceBorderRadius,
|
||||
display: 'flex',
|
||||
height: '80px',
|
||||
padding: offset,
|
||||
width: '300px',
|
||||
}),
|
||||
baseForExternal: css({
|
||||
backgroundColor: theme.colors.action.disabledBackground,
|
||||
border: `${referenceBorderWidth}px dashed ${theme.colors.action.disabledText}`,
|
||||
borderRadius: referenceBorderRadius,
|
||||
height: '80px',
|
||||
flex: 1,
|
||||
width: '300px',
|
||||
}),
|
||||
internalContainer: css({
|
||||
backgroundColor: theme.colors.background.primary,
|
||||
border: `${borderWidth}px solid ${theme.colors.primary.main}`,
|
||||
borderRadius: getInternalRadius(theme, offset, {
|
||||
parentBorderRadius: referenceBorderRadius,
|
||||
parentBorderWidth: referenceBorderWidth,
|
||||
}),
|
||||
flex: 1,
|
||||
}),
|
||||
externalContainer: css({
|
||||
border: `${borderWidth}px solid ${theme.colors.primary.main}`,
|
||||
borderRadius: getExternalRadius(theme, offset, {
|
||||
childBorderRadius: referenceBorderRadius,
|
||||
selfBorderWidth: borderWidth,
|
||||
}),
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
padding: offset,
|
||||
}),
|
||||
});
|
||||
@@ -9,6 +9,7 @@ import { useTheme2 } from '../../themes/ThemeContext';
|
||||
import { allButtonVariants, Button } from '../Button';
|
||||
import { Card } from '../Card/Card';
|
||||
import { CollapsableSection } from '../Collapse/CollapsableSection';
|
||||
import { Combobox } from '../Combobox/Combobox';
|
||||
import { Field } from '../Forms/Field';
|
||||
import { InlineField } from '../Forms/InlineField';
|
||||
import { InlineFieldRow } from '../Forms/InlineFieldRow';
|
||||
@@ -17,7 +18,6 @@ import { Icon } from '../Icon/Icon';
|
||||
import { Input } from '../Input/Input';
|
||||
import { BackgroundColor, BorderColor, Box, BoxShadow } from '../Layout/Box/Box';
|
||||
import { Stack } from '../Layout/Stack/Stack';
|
||||
import { Select } from '../Select/Select';
|
||||
import { Switch } from '../Switch/Switch';
|
||||
import { Text, TextProps } from '../Text/Text';
|
||||
|
||||
@@ -150,8 +150,8 @@ export const ThemeDemo = () => {
|
||||
<Field label="Input disabled" disabled>
|
||||
<Input placeholder="Placeholder" value="Disabled value" />
|
||||
</Field>
|
||||
<Field label="Select">
|
||||
<Select options={selectOptions} value={selectValue} onChange={(v) => setSelectValue(v?.value!)} />
|
||||
<Field label="Combobox">
|
||||
<Combobox options={selectOptions} value={selectValue} onChange={(v) => setSelectValue(v?.value!)} />
|
||||
</Field>
|
||||
<Field label="Radio label">
|
||||
<RadioButtonGroup options={radioOptions} value={radioValue} onChange={setRadioValue} />
|
||||
|
||||
@@ -82,3 +82,55 @@ export const getTooltipContainerStyles = (theme: GrafanaTheme2) => ({
|
||||
borderRadius: theme.shape.radius.default,
|
||||
zIndex: theme.zIndex.tooltip,
|
||||
});
|
||||
|
||||
interface ExternalRadiusAdditionalOptions {
|
||||
selfBorderWidth?: number;
|
||||
childBorderRadius?: number;
|
||||
}
|
||||
/**
|
||||
* Calculates a border radius for an element, based on border radius of its child.
|
||||
*
|
||||
* @param theme
|
||||
* @param offset - The distance to offset from the child element, should be >= 0.
|
||||
* @param additionalOptions
|
||||
* @param additionalOptions.selfBorderWidth - The border width of the element itself (default: 1)
|
||||
* @param additionalOptions.childBorderRadius - The border radius of the child element (default: theme default radius)
|
||||
* @returns A CSS calc() expression that returns the relative external radius value
|
||||
*/
|
||||
export const getExternalRadius = (
|
||||
theme: GrafanaTheme2,
|
||||
offset: number,
|
||||
additionalOptions: ExternalRadiusAdditionalOptions = {}
|
||||
) => {
|
||||
const { selfBorderWidth = 1, childBorderRadius } = additionalOptions;
|
||||
|
||||
const childBorderRadiusPx = childBorderRadius !== undefined ? `${childBorderRadius}px` : theme.shape.radius.default;
|
||||
return `calc(max(0px, ${childBorderRadiusPx} + ${offset}px + ${selfBorderWidth}px))`;
|
||||
};
|
||||
|
||||
interface InternalRadiusAdditionalOptions {
|
||||
parentBorderWidth?: number;
|
||||
parentBorderRadius?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a border radius for an element, based on border radius of its parent.
|
||||
*
|
||||
* @param theme
|
||||
* @param offset - The distance to offset from the parent element, should be >= 0.
|
||||
* @param additionalOptions
|
||||
* @param additionalOptions.parentBorderWidth - The border width of the parent element (default: 1)
|
||||
* @param additionalOptions.parentBorderRadius - The border radius of the parent element (default: theme default radius)
|
||||
* @returns A CSS calc() expression that returns the relative internal radius value
|
||||
*/
|
||||
export const getInternalRadius = (
|
||||
theme: GrafanaTheme2,
|
||||
offset: number,
|
||||
additionalOptions: InternalRadiusAdditionalOptions = {}
|
||||
) => {
|
||||
const { parentBorderWidth = 1, parentBorderRadius } = additionalOptions;
|
||||
|
||||
const parentBorderRadiusPx =
|
||||
parentBorderRadius !== undefined ? `${parentBorderRadius}px` : theme.shape.radius.default;
|
||||
return `calc(max(0px, ${parentBorderRadiusPx} - ${offset}px - ${parentBorderWidth}px))`;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,23 @@ function initI18n() {
|
||||
resources: {},
|
||||
returnEmptyString: false,
|
||||
lng: 'en-US', // this should be the locale of the phrases in our source JSX
|
||||
postProcess: [
|
||||
// Add pseudo processing even if we aren't necessarily going to use it
|
||||
'pseudo',
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
import('i18next-pseudo').then((module) => {
|
||||
const Pseudo = module.default;
|
||||
i18next.use(
|
||||
new Pseudo({
|
||||
languageToPseudo: 'pseudo',
|
||||
enabled: true,
|
||||
wrapped: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ go 1.23.7
|
||||
|
||||
require (
|
||||
github.com/emicklei/go-restful/v3 v3.11.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.270.0
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435
|
||||
github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435
|
||||
github.com/mattbaird/jsonpatch v0.0.0-20240118010651-0ba75a80ca38
|
||||
github.com/stretchr/testify v1.10.0
|
||||
go.opentelemetry.io/otel v1.34.0
|
||||
go.opentelemetry.io/otel v1.35.0
|
||||
k8s.io/api v0.32.1
|
||||
k8s.io/apimachinery v0.32.1
|
||||
k8s.io/apiserver v0.32.1
|
||||
@@ -37,7 +37,7 @@ require (
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/elazarl/goproxy v1.7.1 // indirect
|
||||
github.com/elazarl/goproxy v1.7.2 // indirect
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
@@ -122,15 +122,15 @@ require (
|
||||
go.etcd.io/etcd/client/v3 v3.5.16 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0 // indirect
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.28.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
|
||||
+18
-18
@@ -49,8 +49,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/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/elazarl/goproxy v1.7.1 h1:1P7LPSxbqtNxusFnXclj6O56pjfq1xOQZ6a0mwwKUlY=
|
||||
github.com/elazarl/goproxy v1.7.1/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||
github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
@@ -135,8 +135,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.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.0 h1:4AcuLEE0UeFG0Eo3P8r1FDS89hgZZ73K550DRz1fgjQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.0/go.mod h1:OuwS4c/JYgn0rr/w5zhJBpLo4gKm/vw15RsfpYAvK9Q=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.270.0 h1:SST2Vo//ITQG5h401gC4jTkJpTHy8OV91sf2uDh6M/8=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.270.0/go.mod h1:Z0Cvkj4WGadz6F6FQmK4NGb/hD18kTTNkSqFb97Rfyc=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435 h1:lmw60EW7JWlAEvgggktOyVkH4hF1m/+LSF/Ap0NCyi8=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240808213237-f4d2e064f435/go.mod h1:ORVFiW/KNRY52lNjkGwnFWCxNVfE97bJG2jr2fetq0I=
|
||||
github.com/grafana/grafana/pkg/semconv v0.0.0-20240808213237-f4d2e064f435 h1:SNEeqY22DrGr5E9kGF1mKSqlOom14W9+b1u4XEGJowA=
|
||||
@@ -356,32 +356,32 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.59.0 h1:iQZYNQ7WwIcYXzOPR46FQv9O0dS1PW16RjvR0TjDOe8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.59.0/go.mod h1:54CaSNqYEXvpzDh8KPjiMVoWm60t5R0dZRt0leEPgAs=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0 h1:0tY123n7CdWMem7MOVdKOt0YfshufLCwfE5Bob+hQuM=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.60.0/go.mod h1:CosX/aS4eHnG9D7nESYpV753l4j9q5j3SL/PUYd2lR8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0 h1:D3htJISCUU/wOVlKwisVKancWm+2U4h9xDEaiMkiyRE=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0/go.mod h1:DAX1bsj+uDm2ZuOQH/RgZRx7RQZWyzV5W2WR/0UX8JA=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.28.0 h1:Xx1N6cDr8iWy1Cz6OcY7oS0ACdt/6HDYTdu4KskuC7s=
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.28.0/go.mod h1:iWS+NvC948FyfnJbVfPN9h/8+vr8CR2FPn6XsLRkvH8=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
|
||||
@@ -34,6 +34,7 @@ type FrontendSettingsAuthDTO struct {
|
||||
DisableLogin bool `json:"disableLogin"`
|
||||
BasicAuthStrongPasswordPolicy bool `json:"basicAuthStrongPasswordPolicy"`
|
||||
PasswordlessEnabled bool `json:"passwordlessEnabled"`
|
||||
DisableSignoutMenu bool `json:"disableSignoutMenu"`
|
||||
}
|
||||
|
||||
type FrontendSettingsBuildInfoDTO struct {
|
||||
|
||||
+5
-2
@@ -199,8 +199,11 @@ func (hs *HTTPServer) CreateFolder(c *contextmodel.ReqContext) response.Response
|
||||
return apierrors.ToFolderErrorResponse(err)
|
||||
}
|
||||
|
||||
if err := hs.setDefaultFolderPermissions(c.Req.Context(), cmd.OrgID, cmd.SignedInUser, folder); err != nil {
|
||||
hs.log.Error("Could not set the default folder permissions", "folder", folder.Title, "user", cmd.SignedInUser, "error", err)
|
||||
// Only set default permissions if the Folder API Server is disabled.
|
||||
if !hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesClientDashboardsFolders) {
|
||||
if err := hs.setDefaultFolderPermissions(c.Req.Context(), cmd.OrgID, cmd.SignedInUser, folder); err != nil {
|
||||
hs.log.Error("Could not set the default folder permissions", "folder", folder.Title, "user", cmd.SignedInUser, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear permission cache for the user who's created the folder, so that new permissions are fetched for their next call
|
||||
|
||||
@@ -677,3 +677,94 @@ func TestGetFolderLegacyAndUnifiedStorage(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSetDefaultPermissionsWhenCreatingFolder(t *testing.T) {
|
||||
folderService := &foldertest.FakeService{}
|
||||
setUpRBACGuardian(t)
|
||||
folderWithoutParentInput := "{ \"uid\": \"uid\", \"title\": \"Folder\"}"
|
||||
|
||||
type testCase struct {
|
||||
description string
|
||||
expectedCallsToSetPermissions int
|
||||
expectedCode int
|
||||
expectedFolder *folder.Folder
|
||||
permissions []accesscontrol.Permission
|
||||
featuresArr []any
|
||||
input string
|
||||
}
|
||||
|
||||
tcs := []testCase{
|
||||
{
|
||||
description: "folder creation succeeds, via legacy storage",
|
||||
expectedCallsToSetPermissions: 1,
|
||||
input: folderWithoutParentInput,
|
||||
expectedCode: http.StatusOK,
|
||||
expectedFolder: &folder.Folder{UID: "uid", Title: "Folder"},
|
||||
permissions: []accesscontrol.Permission{{Action: dashboards.ActionFoldersCreate}},
|
||||
},
|
||||
{
|
||||
description: "folder creation succeeds, via API Server",
|
||||
expectedCallsToSetPermissions: 0,
|
||||
input: folderWithoutParentInput,
|
||||
expectedCode: http.StatusOK,
|
||||
expectedFolder: &folder.Folder{UID: "uid", Title: "Folder"},
|
||||
permissions: []accesscontrol.Permission{{Action: dashboards.ActionFoldersCreate}},
|
||||
featuresArr: []any{featuremgmt.FlagKubernetesClientDashboardsFolders},
|
||||
},
|
||||
}
|
||||
|
||||
// we need to save these values because they are defined at `setting` package level
|
||||
// and modified when we invoke setting.NewCfgFromINIFile
|
||||
prevCookieSameSiteDisabled := setting.CookieSameSiteDisabled
|
||||
prevCookieSameSiteMode := setting.CookieSameSiteMode
|
||||
|
||||
cfg := setting.NewCfg()
|
||||
cfg.Raw.Section("rbac").Key("resources_with_managed_permissions_on_creation").SetValue("folder")
|
||||
tmpCfg, err := setting.NewCfgFromINIFile(cfg.Raw)
|
||||
require.NoError(t, err)
|
||||
cfg.RBAC = tmpCfg.RBAC
|
||||
|
||||
// restore previous values so other tests don't break
|
||||
// ex: TestHTTPServer_RotateUserAuthToken
|
||||
setting.CookieSameSiteDisabled = prevCookieSameSiteDisabled
|
||||
setting.CookieSameSiteMode = prevCookieSameSiteMode
|
||||
|
||||
for _, tc := range tcs {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
folderService.ExpectedFolder = tc.expectedFolder
|
||||
folderPermService := acmock.NewMockedPermissionsService()
|
||||
folderPermService.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||
|
||||
srv := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||
hs.Cfg = cfg
|
||||
|
||||
featuresArr := append(tc.featuresArr, featuremgmt.FlagNestedFolders)
|
||||
hs.Features = featuremgmt.WithFeatures(
|
||||
featuresArr...,
|
||||
)
|
||||
hs.folderService = folderService
|
||||
hs.folderPermissionsService = folderPermService
|
||||
hs.accesscontrolService = actest.FakeService{}
|
||||
})
|
||||
|
||||
input := strings.NewReader(tc.input)
|
||||
req := srv.NewPostRequest("/api/folders", input)
|
||||
req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, tc.permissions))
|
||||
resp, err := srv.SendJSON(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expectedCode, resp.StatusCode)
|
||||
|
||||
folder := dtos.Folder{}
|
||||
err = json.NewDecoder(resp.Body).Decode(&folder)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, resp.Body.Close())
|
||||
|
||||
folderPermService.AssertNumberOfCalls(t, "SetPermissions", tc.expectedCallsToSetPermissions)
|
||||
|
||||
if tc.expectedCode == http.StatusOK {
|
||||
assert.Equal(t, "uid", folder.UID)
|
||||
assert.Equal(t, "Folder", folder.Title)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,6 +367,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
OktaSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.OktaProviderName]),
|
||||
DisableLogin: hs.Cfg.DisableLogin,
|
||||
BasicAuthStrongPasswordPolicy: hs.Cfg.BasicAuthStrongPasswordPolicy,
|
||||
DisableSignoutMenu: hs.Cfg.DisableSignoutMenu,
|
||||
}
|
||||
|
||||
if hs.Cfg.PasswordlessMagicLinkAuth.Enabled && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagPasswordlessMagicLinkAuthentication) {
|
||||
|
||||
@@ -23,7 +23,6 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -35,9 +34,9 @@ require (
|
||||
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
golang.org/x/crypto v0.35.0 // indirect
|
||||
golang.org/x/net v0.36.0 // indirect
|
||||
golang.org/x/sync v0.11.0 // indirect
|
||||
|
||||
+10
-10
@@ -74,16 +74,16 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
|
||||
@@ -47,79 +47,127 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
|
||||
func Convert_V0_to_V1(in *dashboardV0.Dashboard, out *dashboardV1.Dashboard, scope conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Spec = in.Spec
|
||||
out.Status = &dashboardV1.DashboardStatus{
|
||||
ConversionStatus: &dashboardV1.ConversionStatus{
|
||||
|
||||
out.Spec.Object = in.Spec.Object
|
||||
|
||||
out.Status = dashboardV1.DashboardStatus{
|
||||
Conversion: &dashboardV1.DashboardConversionStatus{
|
||||
StoredVersion: dashboardV0.VERSION,
|
||||
},
|
||||
}
|
||||
err := migration.Migrate(out.Spec.Object, schemaversion.LATEST_VERSION)
|
||||
if err != nil {
|
||||
out.Status.ConversionStatus.Failed = true
|
||||
out.Status.ConversionStatus.Error = err.Error()
|
||||
|
||||
if err := migration.Migrate(out.Spec.Object, schemaversion.LATEST_VERSION); err != nil {
|
||||
out.Status.Conversion.Failed = true
|
||||
out.Status.Conversion.Error = err.Error()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_V0_to_V2(in *dashboardV0.Dashboard, out *dashboardV2.Dashboard, scope conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Spec = in.Spec
|
||||
out.Status = &dashboardV2.DashboardStatus{
|
||||
ConversionStatus: &dashboardV2.ConversionStatus{
|
||||
|
||||
// TODO (@radiohead): implement V0 to V2 conversion
|
||||
// This is the bare minimum conversion that is needed to make the dashboard servable.
|
||||
|
||||
if v, ok := in.Spec.Object["title"]; ok {
|
||||
if title, ok := v.(string); ok {
|
||||
out.Spec.Title = title
|
||||
}
|
||||
}
|
||||
|
||||
// We need to make sure the layout is set to some value, otherwise the JSON marshaling will fail.
|
||||
out.Spec.Layout = dashboardV2.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind{
|
||||
GridLayoutKind: &dashboardV2.DashboardGridLayoutKind{
|
||||
Kind: "GridLayout",
|
||||
Spec: dashboardV2.DashboardGridLayoutSpec{},
|
||||
},
|
||||
}
|
||||
|
||||
out.Status = dashboardV2.DashboardStatus{
|
||||
Conversion: &dashboardV2.DashboardConversionStatus{
|
||||
StoredVersion: dashboardV0.VERSION,
|
||||
Failed: true,
|
||||
Error: "backend conversion not yet implemented",
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_V1_to_V0(in *dashboardV1.Dashboard, out *dashboardV0.Dashboard, scope conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Spec = in.Spec
|
||||
out.Status = &dashboardV0.DashboardStatus{
|
||||
ConversionStatus: &dashboardV0.ConversionStatus{
|
||||
|
||||
out.Spec.Object = in.Spec.Object
|
||||
|
||||
out.Status = dashboardV0.DashboardStatus{
|
||||
Conversion: &dashboardV0.DashboardConversionStatus{
|
||||
StoredVersion: dashboardV1.VERSION,
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_V1_to_V2(in *dashboardV1.Dashboard, out *dashboardV2.Dashboard, scope conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Spec = in.Spec
|
||||
out.Status = &dashboardV2.DashboardStatus{
|
||||
ConversionStatus: &dashboardV2.ConversionStatus{
|
||||
|
||||
// TODO (@radiohead): implement V1 to V2 conversion
|
||||
// This is the bare minimum conversion that is needed to make the dashboard servable.
|
||||
|
||||
if v, ok := in.Spec.Object["title"]; ok {
|
||||
if title, ok := v.(string); ok {
|
||||
out.Spec.Title = title
|
||||
}
|
||||
}
|
||||
|
||||
// We need to make sure the layout is set to some value, otherwise the JSON marshaling will fail.
|
||||
out.Spec.Layout = dashboardV2.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind{
|
||||
GridLayoutKind: &dashboardV2.DashboardGridLayoutKind{
|
||||
Kind: "GridLayout",
|
||||
Spec: dashboardV2.DashboardGridLayoutSpec{},
|
||||
},
|
||||
}
|
||||
|
||||
out.Status = dashboardV2.DashboardStatus{
|
||||
Conversion: &dashboardV2.DashboardConversionStatus{
|
||||
StoredVersion: dashboardV1.VERSION,
|
||||
Failed: true,
|
||||
Error: "backend conversion not yet implemented",
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_V2_to_V0(in *dashboardV2.Dashboard, out *dashboardV0.Dashboard, scope conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Spec = in.Spec
|
||||
out.Status = &dashboardV0.DashboardStatus{
|
||||
ConversionStatus: &dashboardV0.ConversionStatus{
|
||||
|
||||
// TODO: implement V2 to V0 conversion
|
||||
|
||||
out.Status = dashboardV0.DashboardStatus{
|
||||
Conversion: &dashboardV0.DashboardConversionStatus{
|
||||
StoredVersion: dashboardV2.VERSION,
|
||||
Failed: true,
|
||||
Error: "backend conversion not yet implemented",
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_V2_to_V1(in *dashboardV2.Dashboard, out *dashboardV1.Dashboard, scope conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Spec = in.Spec
|
||||
out.Status = &dashboardV1.DashboardStatus{
|
||||
ConversionStatus: &dashboardV1.ConversionStatus{
|
||||
|
||||
// TODO: implement V2 to V1 conversion
|
||||
|
||||
out.Status = dashboardV1.DashboardStatus{
|
||||
Conversion: &dashboardV1.DashboardConversionStatus{
|
||||
StoredVersion: dashboardV2.VERSION,
|
||||
Failed: true,
|
||||
Error: "backend conversion not yet implemented",
|
||||
},
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package v0alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
const (
|
||||
// Group is the API group used by all kinds in this package
|
||||
Group = "dashboard.grafana.app"
|
||||
// Version is the API version used by all kinds in this package
|
||||
Version = "v0alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package
|
||||
GroupVersion = schema.GroupVersion{
|
||||
Group: Group,
|
||||
Version: Version,
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,28 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
)
|
||||
|
||||
// DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding
|
||||
type DashboardJSONCodec struct{}
|
||||
|
||||
// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into`
|
||||
func (*DashboardJSONCodec) Read(reader io.Reader, into resource.Object) error {
|
||||
return json.NewDecoder(reader).Decode(into)
|
||||
}
|
||||
|
||||
// Write writes JSON-encoded bytes into `writer` marshaled from `from`
|
||||
func (*DashboardJSONCodec) Write(writer io.Writer, from resource.Object) error {
|
||||
return json.NewEncoder(writer).Encode(from)
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Codec = &DashboardJSONCodec{}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
time "time"
|
||||
)
|
||||
|
||||
// metadata contains embedded CommonMetadata and can be extended with custom string fields
|
||||
// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
|
||||
// without external reference as using the CommonMetadata reference breaks thema codegen.
|
||||
type DashboardMetadata struct {
|
||||
UpdateTimestamp time.Time `json:"updateTimestamp"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
Uid string `json:"uid"`
|
||||
CreationTimestamp time.Time `json:"creationTimestamp"`
|
||||
DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"`
|
||||
Finalizers []string `json:"finalizers"`
|
||||
ResourceVersion string `json:"resourceVersion"`
|
||||
Generation int64 `json:"generation"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
}
|
||||
|
||||
// NewDashboardMetadata creates a new DashboardMetadata object.
|
||||
func NewDashboardMetadata() *DashboardMetadata {
|
||||
return &DashboardMetadata{}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type Dashboard struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
|
||||
|
||||
// Spec is the spec of the Dashboard
|
||||
Spec DashboardSpec `json:"spec" yaml:"spec"`
|
||||
|
||||
Status DashboardStatus `json:"status" yaml:"status"`
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetSpec() any {
|
||||
return o.Spec
|
||||
}
|
||||
|
||||
func (o *Dashboard) SetSpec(spec any) error {
|
||||
cast, ok := spec.(DashboardSpec)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec)
|
||||
}
|
||||
o.Spec = cast
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetSubresources() map[string]any {
|
||||
return map[string]any{
|
||||
"status": o.Status,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetSubresource(name string) (any, bool) {
|
||||
switch name {
|
||||
case "status":
|
||||
return o.Status, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Dashboard) SetSubresource(name string, value any) error {
|
||||
switch name {
|
||||
case "status":
|
||||
cast, ok := value.(DashboardStatus)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set status type %#v, not of type DashboardStatus", value)
|
||||
}
|
||||
o.Status = cast
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("subresource '%s' does not exist", name)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetStaticMetadata() resource.StaticMetadata {
|
||||
gvk := o.GroupVersionKind()
|
||||
return resource.StaticMetadata{
|
||||
Name: o.ObjectMeta.Name,
|
||||
Namespace: o.ObjectMeta.Namespace,
|
||||
Group: gvk.Group,
|
||||
Version: gvk.Version,
|
||||
Kind: gvk.Kind,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Dashboard) SetStaticMetadata(metadata resource.StaticMetadata) {
|
||||
o.Name = metadata.Name
|
||||
o.Namespace = metadata.Namespace
|
||||
o.SetGroupVersionKind(schema.GroupVersionKind{
|
||||
Group: metadata.Group,
|
||||
Version: metadata.Version,
|
||||
Kind: metadata.Kind,
|
||||
})
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetCommonMetadata() resource.CommonMetadata {
|
||||
dt := o.DeletionTimestamp
|
||||
var deletionTimestamp *time.Time
|
||||
if dt != nil {
|
||||
deletionTimestamp = &dt.Time
|
||||
}
|
||||
// Legacy ExtraFields support
|
||||
extraFields := make(map[string]any)
|
||||
if o.Annotations != nil {
|
||||
extraFields["annotations"] = o.Annotations
|
||||
}
|
||||
if o.ManagedFields != nil {
|
||||
extraFields["managedFields"] = o.ManagedFields
|
||||
}
|
||||
if o.OwnerReferences != nil {
|
||||
extraFields["ownerReferences"] = o.OwnerReferences
|
||||
}
|
||||
return resource.CommonMetadata{
|
||||
UID: string(o.UID),
|
||||
ResourceVersion: o.ResourceVersion,
|
||||
Generation: o.Generation,
|
||||
Labels: o.Labels,
|
||||
CreationTimestamp: o.CreationTimestamp.Time,
|
||||
DeletionTimestamp: deletionTimestamp,
|
||||
Finalizers: o.Finalizers,
|
||||
UpdateTimestamp: o.GetUpdateTimestamp(),
|
||||
CreatedBy: o.GetCreatedBy(),
|
||||
UpdatedBy: o.GetUpdatedBy(),
|
||||
ExtraFields: extraFields,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Dashboard) SetCommonMetadata(metadata resource.CommonMetadata) {
|
||||
o.UID = types.UID(metadata.UID)
|
||||
o.ResourceVersion = metadata.ResourceVersion
|
||||
o.Generation = metadata.Generation
|
||||
o.Labels = metadata.Labels
|
||||
o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp)
|
||||
if metadata.DeletionTimestamp != nil {
|
||||
dt := metav1.NewTime(*metadata.DeletionTimestamp)
|
||||
o.DeletionTimestamp = &dt
|
||||
} else {
|
||||
o.DeletionTimestamp = nil
|
||||
}
|
||||
o.Finalizers = metadata.Finalizers
|
||||
if o.Annotations == nil {
|
||||
o.Annotations = make(map[string]string)
|
||||
}
|
||||
if !metadata.UpdateTimestamp.IsZero() {
|
||||
o.SetUpdateTimestamp(metadata.UpdateTimestamp)
|
||||
}
|
||||
if metadata.CreatedBy != "" {
|
||||
o.SetCreatedBy(metadata.CreatedBy)
|
||||
}
|
||||
if metadata.UpdatedBy != "" {
|
||||
o.SetUpdatedBy(metadata.UpdatedBy)
|
||||
}
|
||||
// Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields
|
||||
if metadata.ExtraFields != nil {
|
||||
if annotations, ok := metadata.ExtraFields["annotations"]; ok {
|
||||
if cast, ok := annotations.(map[string]string); ok {
|
||||
o.Annotations = cast
|
||||
}
|
||||
}
|
||||
if managedFields, ok := metadata.ExtraFields["managedFields"]; ok {
|
||||
if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok {
|
||||
o.ManagedFields = cast
|
||||
}
|
||||
}
|
||||
if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok {
|
||||
if cast, ok := ownerReferences.([]metav1.OwnerReference); ok {
|
||||
o.OwnerReferences = cast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetCreatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/createdBy"]
|
||||
}
|
||||
|
||||
func (o *Dashboard) SetCreatedBy(createdBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetUpdateTimestamp() time.Time {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"])
|
||||
return parsed
|
||||
}
|
||||
|
||||
func (o *Dashboard) SetUpdateTimestamp(updateTimestamp time.Time) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
func (o *Dashboard) GetUpdatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/updatedBy"]
|
||||
}
|
||||
|
||||
func (o *Dashboard) SetUpdatedBy(updatedBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy
|
||||
}
|
||||
|
||||
func (o *Dashboard) Copy() resource.Object {
|
||||
return resource.CopyObject(o)
|
||||
}
|
||||
|
||||
func (o *Dashboard) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.Object = &Dashboard{}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardList struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []Dashboard `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
func (o *DashboardList) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
func (o *DashboardList) Copy() resource.ListObject {
|
||||
cpy := &DashboardList{
|
||||
TypeMeta: o.TypeMeta,
|
||||
Items: make([]Dashboard, len(o.Items)),
|
||||
}
|
||||
o.ListMeta.DeepCopyInto(&cpy.ListMeta)
|
||||
for i := 0; i < len(o.Items); i++ {
|
||||
if item, ok := o.Items[i].Copy().(*Dashboard); ok {
|
||||
cpy.Items[i] = *item
|
||||
}
|
||||
}
|
||||
return cpy
|
||||
}
|
||||
|
||||
func (o *DashboardList) GetItems() []resource.Object {
|
||||
items := make([]resource.Object, len(o.Items))
|
||||
for i := 0; i < len(o.Items); i++ {
|
||||
items[i] = &o.Items[i]
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func (o *DashboardList) SetItems(items []resource.Object) {
|
||||
o.Items = make([]Dashboard, len(items))
|
||||
for i := 0; i < len(items); i++ {
|
||||
o.Items[i] = *items[i].(*Dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.ListObject = &DashboardList{}
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
)
|
||||
|
||||
// schema is unexported to prevent accidental overwrites
|
||||
var (
|
||||
schemaDashboard = resource.NewSimpleSchema("dashboard.grafana.app", "v0alpha1", &Dashboard{}, &DashboardList{}, resource.WithKind("Dashboard"),
|
||||
resource.WithPlural("dashboards"), resource.WithScope(resource.NamespacedScope))
|
||||
kindDashboard = resource.Kind{
|
||||
Schema: schemaDashboard,
|
||||
Codecs: map[resource.KindEncoding]resource.Codec{
|
||||
resource.KindEncodingJSON: &DashboardJSONCodec{},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Kind returns a resource.Kind for this Schema with a JSON codec
|
||||
func DashboardKind() resource.Kind {
|
||||
return kindDashboard
|
||||
}
|
||||
|
||||
// Schema returns a resource.SimpleSchema representation of Dashboard
|
||||
func DashboardSchema() *resource.SimpleSchema {
|
||||
return schemaDashboard
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Schema = kindDashboard
|
||||
@@ -0,0 +1,13 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardSpec = common.Unstructured
|
||||
|
||||
// NewDashboardSpec creates a new Spec object.
|
||||
func NewDashboardSpec() *DashboardSpec {
|
||||
return &DashboardSpec{}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
@@ -0,0 +1,34 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// ConversionStatus is the status of the conversion of the dashboard.
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardConversionStatus struct {
|
||||
// Whether from another version has failed.
|
||||
// If true, means that the dashboard is not valid,
|
||||
// and the caller should instead fetch the stored version.
|
||||
Failed bool `json:"failed"`
|
||||
// The version which was stored when the dashboard was created / updated.
|
||||
// Fetching this version should always succeed.
|
||||
StoredVersion string `json:"storedVersion"`
|
||||
// The error message from the conversion.
|
||||
// Empty if the conversion has not failed.
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// NewDashboardConversionStatus creates a new DashboardConversionStatus object.
|
||||
func NewDashboardConversionStatus() *DashboardConversionStatus {
|
||||
return &DashboardConversionStatus{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type DashboardStatus struct {
|
||||
// Optional conversion status.
|
||||
Conversion *DashboardConversionStatus `json:"conversion,omitempty"`
|
||||
}
|
||||
|
||||
// NewDashboardStatus creates a new DashboardStatus object.
|
||||
func NewDashboardStatus() *DashboardStatus {
|
||||
return &DashboardStatus{}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package v0alpha1
|
||||
|
||||
// TODO: these should be automatically generated by the SDK.
|
||||
|
||||
func (in *Dashboard) DeepCopyInto(out *Dashboard) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
}
|
||||
|
||||
func (in *Dashboard) DeepCopy() *Dashboard {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Dashboard)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
func (in *DashboardList) DeepCopyInto(out *DashboardList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Dashboard, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (in *DashboardList) DeepCopy() *DashboardList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DashboardList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +k8s:openapi-gen=true
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:conversion-gen=github.com/grafana/grafana/pkg/apis/dashboard
|
||||
// +groupName=dashboard.grafana.app
|
||||
|
||||
// NOTE (@radiohead): we do not use package-wide deepcopy generation
|
||||
// because grafana-app-sdk already provides deepcopy functions.
|
||||
// Kinds which are not generated by the SDK are explicitly opted in to deepcopy generation.
|
||||
|
||||
package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type SearchResults struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -32,11 +33,13 @@ type SearchResults struct {
|
||||
Facets map[string]FacetResult `json:"facets,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type SortBy struct {
|
||||
Field string `json:"field"`
|
||||
Descending bool `json:"desc,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type SortableFields struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -45,12 +48,14 @@ type SortableFields struct {
|
||||
Fields []SortableField `json:"fields"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type SortableField struct {
|
||||
Field string `json:"string,omitempty"`
|
||||
Display string `json:"display,omitempty"`
|
||||
Type string `json:"type,omitempty"` // string or number
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type DashboardHit struct {
|
||||
// Dashboard or folder
|
||||
Resource string `json:"resource"` // dashboards | folders
|
||||
@@ -70,6 +75,7 @@ type DashboardHit struct {
|
||||
Explain *common.Unstructured `json:"explain,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type FacetResult struct {
|
||||
Field string `json:"field,omitempty"`
|
||||
// The distinct terms
|
||||
@@ -80,6 +86,7 @@ type FacetResult struct {
|
||||
Terms []TermFacet `json:"terms,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type TermFacet struct {
|
||||
Term string `json:"term,omitempty"`
|
||||
Count int64 `json:"count,omitempty"`
|
||||
|
||||
@@ -7,40 +7,7 @@ import (
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type Dashboard struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// The dashboard body (unstructured for now)
|
||||
Spec common.Unstructured `json:"spec"`
|
||||
|
||||
// Optional dashboard status
|
||||
Status *DashboardStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
type DashboardStatus struct {
|
||||
ConversionStatus *ConversionStatus `json:"conversion,omitempty"`
|
||||
}
|
||||
|
||||
type ConversionStatus struct {
|
||||
Failed bool `json:"failed,omitempty"`
|
||||
StoredVersion string `json:"storedVersion,omitempty"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type DashboardList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
Items []Dashboard `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type DashboardVersionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -50,6 +17,7 @@ type DashboardVersionList struct {
|
||||
Items []DashboardVersionInfo `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type DashboardVersionInfo struct {
|
||||
// The internal ID for this version (will be replaced with resourceVersion)
|
||||
Version int `json:"version"`
|
||||
@@ -67,6 +35,7 @@ type DashboardVersionInfo struct {
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:conversion-gen:explicit-from=net/url.Values
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type VersionsQueryOptions struct {
|
||||
@@ -80,6 +49,7 @@ type VersionsQueryOptions struct {
|
||||
Version int64 `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LibraryPanel struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -95,6 +65,7 @@ type LibraryPanel struct {
|
||||
Status *LibraryPanelStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type LibraryPanelList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
@@ -104,6 +75,7 @@ type LibraryPanelList struct {
|
||||
Items []LibraryPanel `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type LibraryPanelSpec struct {
|
||||
// The panel type
|
||||
Type string `json:"type"`
|
||||
@@ -131,6 +103,7 @@ type LibraryPanelSpec struct {
|
||||
Targets []data.DataQuery `json:"targets,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type LibraryPanelStatus struct {
|
||||
// Translation warnings (mostly things that were in SQL columns but not found in the saved body)
|
||||
Warnings []string `json:"warnings,omitempty"`
|
||||
@@ -140,6 +113,7 @@ type LibraryPanelStatus struct {
|
||||
}
|
||||
|
||||
// This is like the legacy DTO where access and metadata are all returned in a single call
|
||||
// +k8s:deepcopy-gen=true
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
type DashboardWithAccessInfo struct {
|
||||
Dashboard `json:",inline"`
|
||||
@@ -147,7 +121,7 @@ type DashboardWithAccessInfo struct {
|
||||
Access DashboardAccess `json:"access"`
|
||||
}
|
||||
|
||||
// Information about how the requesting user can use a given dashboard
|
||||
// +k8s:deepcopy-gen=true
|
||||
type DashboardAccess struct {
|
||||
// Metadata fields
|
||||
Slug string `json:"slug,omitempty"`
|
||||
@@ -162,11 +136,13 @@ type DashboardAccess struct {
|
||||
AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type AnnotationPermission struct {
|
||||
Dashboard AnnotationActions `json:"dashboard"`
|
||||
Organization AnnotationActions `json:"organization"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=true
|
||||
type AnnotationActions struct {
|
||||
CanAdd bool `json:"canAdd"`
|
||||
CanEdit bool `json:"canEdit"`
|
||||
|
||||
@@ -46,54 +46,6 @@ func (in *AnnotationPermission) DeepCopy() *AnnotationPermission {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ConversionStatus) DeepCopyInto(out *ConversionStatus) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionStatus.
|
||||
func (in *ConversionStatus) DeepCopy() *ConversionStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ConversionStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Dashboard) DeepCopyInto(out *Dashboard) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
if in.Status != nil {
|
||||
in, out := &in.Status, &out.Status
|
||||
*out = new(DashboardStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Dashboard.
|
||||
func (in *Dashboard) DeepCopy() *Dashboard {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Dashboard)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Dashboard) 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 *DashboardAccess) DeepCopyInto(out *DashboardAccess) {
|
||||
*out = *in
|
||||
@@ -144,60 +96,6 @@ func (in *DashboardHit) DeepCopy() *DashboardHit {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DashboardList) DeepCopyInto(out *DashboardList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Dashboard, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList.
|
||||
func (in *DashboardList) DeepCopy() *DashboardList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DashboardList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DashboardList) 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 *DashboardStatus) DeepCopyInto(out *DashboardStatus) {
|
||||
*out = *in
|
||||
if in.ConversionStatus != nil {
|
||||
in, out := &in.ConversionStatus, &out.ConversionStatus
|
||||
*out = new(ConversionStatus)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus.
|
||||
func (in *DashboardStatus) DeepCopy() *DashboardStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DashboardStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DashboardVersionInfo) DeepCopyInto(out *DashboardVersionInfo) {
|
||||
*out = *in
|
||||
|
||||
@@ -8,34 +8,38 @@
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
commonv0alpha1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
common "k8s.io/kube-openapi/pkg/common"
|
||||
spec "k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||
return map[string]common.OpenAPIDefinition{
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationActions": schema_pkg_apis_dashboard_v0alpha1_AnnotationActions(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus": schema_pkg_apis_dashboard_v0alpha1_ConversionStatus(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.Dashboard": schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardAccess": schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardHit": schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardList": schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus": schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionInfo(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.FacetResult": schema_pkg_apis_dashboard_v0alpha1_FacetResult(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanel": schema_pkg_apis_dashboard_v0alpha1_LibraryPanel(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelStatus(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SearchResults": schema_pkg_apis_dashboard_v0alpha1_SearchResults(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortBy": schema_pkg_apis_dashboard_v0alpha1_SortBy(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableField": schema_pkg_apis_dashboard_v0alpha1_SortableField(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableFields": schema_pkg_apis_dashboard_v0alpha1_SortableFields(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.TermFacet": schema_pkg_apis_dashboard_v0alpha1_TermFacet(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v0alpha1_VersionsQueryOptions(ref),
|
||||
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured": commonv0alpha1.Unstructured{}.OpenAPIDefinition(),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationActions": schema_pkg_apis_dashboard_v0alpha1_AnnotationActions(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.Dashboard": schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardAccess": schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardConversionStatus": schema_pkg_apis_dashboard_v0alpha1_DashboardConversionStatus(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardHit": schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardJSONCodec": schema_pkg_apis_dashboard_v0alpha1_DashboardJSONCodec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardList": schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardMetadata": schema_pkg_apis_dashboard_v0alpha1_DashboardMetadata(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus": schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionInfo(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.FacetResult": schema_pkg_apis_dashboard_v0alpha1_FacetResult(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanel": schema_pkg_apis_dashboard_v0alpha1_LibraryPanel(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelList(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelSpec(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelStatus(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SearchResults": schema_pkg_apis_dashboard_v0alpha1_SearchResults(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortBy": schema_pkg_apis_dashboard_v0alpha1_SortBy(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableField": schema_pkg_apis_dashboard_v0alpha1_SortableField(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableFields": schema_pkg_apis_dashboard_v0alpha1_SortableFields(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.TermFacet": schema_pkg_apis_dashboard_v0alpha1_TermFacet(ref),
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v0alpha1_VersionsQueryOptions(ref),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,36 +104,6 @@ func schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref common.Referenc
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_ConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"failed": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"storedVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"error": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -152,25 +126,24 @@ func schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref common.ReferenceCallback)
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The dashboard body (unstructured for now)",
|
||||
Description: "Spec is the spec of the Dashboard",
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Optional dashboard status",
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"),
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"spec"},
|
||||
Required: []string{"metadata", "spec", "status"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
@@ -182,8 +155,7 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref common.ReferenceCall
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Information about how the requesting user can use a given dashboard",
|
||||
Type: []string{"object"},
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"slug": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -248,6 +220,44 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref common.ReferenceCall
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_DashboardConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "ConversionStatus is the status of the conversion of the dashboard.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"failed": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Whether from another version has failed. If true, means that the dashboard is not valid, and the caller should instead fetch the stored version.",
|
||||
Default: false,
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"storedVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The version which was stored when the dashboard was created / updated. Fetching this version should always succeed.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"error": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The error message from the conversion. Empty if the conversion has not failed.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"failed", "storedVersion", "error"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -328,6 +338,17 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref common.ReferenceCallbac
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_DashboardJSONCodec(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding",
|
||||
Type: []string{"object"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -368,6 +389,7 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref common.ReferenceCallba
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"metadata", "items"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
@@ -375,6 +397,102 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref common.ReferenceCallba
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_DashboardMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "metadata contains embedded CommonMetadata and can be extended with custom string fields without external reference as using the CommonMetadata reference breaks thema codegen.",
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"updateTimestamp": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "date-time",
|
||||
},
|
||||
},
|
||||
"createdBy": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"uid": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"creationTimestamp": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "date-time",
|
||||
},
|
||||
},
|
||||
"deletionTimestamp": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "date-time",
|
||||
},
|
||||
},
|
||||
"finalizers": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"resourceVersion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"generation": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"updatedBy": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"labels": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
AdditionalProperties: &spec.SchemaOrBool{
|
||||
Allows: true,
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"updateTimestamp", "createdBy", "uid", "creationTimestamp", "finalizers", "resourceVersion", "generation", "updatedBy", "labels"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
@@ -383,14 +501,15 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref common.ReferenceCall
|
||||
Properties: map[string]spec.Schema{
|
||||
"conversion": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus"),
|
||||
Description: "Optional conversion status.",
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardConversionStatus"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus"},
|
||||
"github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardConversionStatus"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,21 +633,20 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref common.Refer
|
||||
},
|
||||
"metadata": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The dashboard body (unstructured for now)",
|
||||
Description: "Spec is the spec of the Dashboard",
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"),
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Optional dashboard status",
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"),
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"),
|
||||
},
|
||||
},
|
||||
"access": {
|
||||
@@ -538,7 +656,7 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref common.Refer
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"spec", "access"},
|
||||
Required: []string{"metadata", "spec", "status", "access"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,DashboardHit,Tags
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,DashboardMetadata,Finalizers
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,FacetResult,Terms
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,LibraryPanelStatus,Warnings
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SearchResults,Hits
|
||||
API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortableFields,Fields
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,DashboardStatus,ConversionStatus
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1,Unstructured,Object
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortBy,Descending
|
||||
API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortableField,Field
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package v1alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
const (
|
||||
// Group is the API group used by all kinds in this package
|
||||
Group = "dashboard.grafana.app"
|
||||
// Version is the API version used by all kinds in this package
|
||||
Version = "v1alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package
|
||||
GroupVersion = schema.GroupVersion{
|
||||
Group: Group,
|
||||
Version: Version,
|
||||
}
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user