merge with main
This commit is contained in:
+2
-95
@@ -518,120 +518,30 @@ exports[`better eslint`] = {
|
||||
"packages/grafana-sql/src/components/visual-query-builder/AwesomeQueryBuilder.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Alert/Alert.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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Card/Card.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Cascader/Cascader.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Combobox/MultiCombobox.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Combobox/ValuePill.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Combobox/useOptions.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/ConfirmModal/ConfirmContent.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataLinks/DataLinkEditor.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 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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/BasicAuthSettings.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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.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 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"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "7"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.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 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"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "6"],
|
||||
[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 in text props. Wrap text with <Trans /> or use t()", "10"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "11"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "12"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.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 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"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/SecureSocksProxySettings.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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.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 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"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "6"],
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "7"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DataSourceSettings/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.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"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.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 in text props. Wrap text with <Trans /> or use t()", "2"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
@@ -1575,9 +1485,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "7"]
|
||||
],
|
||||
"public/app/features/alerting/unified/RuleViewer.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
"public/app/features/alerting/unified/Settings.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"],
|
||||
|
||||
+41
-41
@@ -18,7 +18,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd
|
||||
@@ -69,7 +69,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- go install github.com/bazelbuild/buildtools/buildifier@latest
|
||||
@@ -112,7 +112,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -170,7 +170,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -309,7 +309,7 @@ steps:
|
||||
path: /github-app
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -427,7 +427,7 @@ steps:
|
||||
path: /github-app
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -517,7 +517,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd
|
||||
@@ -642,7 +642,7 @@ steps:
|
||||
path: /github-app
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- mkdir -p bin
|
||||
@@ -713,7 +713,7 @@ steps:
|
||||
-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.5 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
--build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.20.6
|
||||
--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
|
||||
> packages.txt
|
||||
@@ -770,7 +770,7 @@ steps:
|
||||
GF_APP_MODE: development
|
||||
GF_SERVER_HTTP_PORT: "3001"
|
||||
GF_SERVER_ROUTER_LOGGING: "1"
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: grafana-server
|
||||
- commands:
|
||||
- ./bin/build e2e-tests --port 3001 --suite dashboards-suite
|
||||
@@ -1114,7 +1114,7 @@ steps:
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -1280,7 +1280,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -1637,7 +1637,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -1708,7 +1708,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -1766,7 +1766,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -1842,7 +1842,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -1922,7 +1922,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd
|
||||
@@ -1988,7 +1988,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -2063,7 +2063,7 @@ steps:
|
||||
path: /github-app
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- mkdir -p bin
|
||||
@@ -2133,7 +2133,7 @@ steps:
|
||||
-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.5 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
--build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.20.6
|
||||
--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
|
||||
> packages.txt
|
||||
@@ -2194,7 +2194,7 @@ steps:
|
||||
GF_APP_MODE: development
|
||||
GF_SERVER_HTTP_PORT: "3001"
|
||||
GF_SERVER_ROUTER_LOGGING: "1"
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: grafana-server
|
||||
- commands:
|
||||
- ./bin/build e2e-tests --port 3001 --suite dashboards-suite
|
||||
@@ -2611,7 +2611,7 @@ steps:
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -2856,7 +2856,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -2912,7 +2912,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -2986,7 +2986,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -3064,7 +3064,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd
|
||||
@@ -3169,7 +3169,7 @@ steps:
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -3372,7 +3372,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- mkdir -p bin
|
||||
@@ -3504,7 +3504,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- mkdir -p bin
|
||||
@@ -3994,7 +3994,7 @@ steps:
|
||||
environment:
|
||||
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
|
||||
from_secret: dagger_token
|
||||
ALPINE_BASE: alpine:3.20.6
|
||||
ALPINE_BASE: alpine:3.21.3
|
||||
CDN_DESTINATION:
|
||||
from_secret: rgm_cdn_destination
|
||||
DESTINATION:
|
||||
@@ -4069,7 +4069,7 @@ steps:
|
||||
environment:
|
||||
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
|
||||
from_secret: dagger_token
|
||||
ALPINE_BASE: alpine:3.20.6
|
||||
ALPINE_BASE: alpine:3.21.3
|
||||
CDN_DESTINATION:
|
||||
from_secret: rgm_cdn_destination
|
||||
DESTINATION:
|
||||
@@ -4186,7 +4186,7 @@ steps:
|
||||
environment:
|
||||
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
|
||||
from_secret: dagger_token
|
||||
ALPINE_BASE: alpine:3.20.6
|
||||
ALPINE_BASE: alpine:3.21.3
|
||||
CDN_DESTINATION:
|
||||
from_secret: rgm_cdn_destination
|
||||
DESTINATION:
|
||||
@@ -4288,7 +4288,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -4342,7 +4342,7 @@ services: []
|
||||
steps:
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -4423,7 +4423,7 @@ steps:
|
||||
environment:
|
||||
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
|
||||
from_secret: dagger_token
|
||||
ALPINE_BASE: alpine:3.20.6
|
||||
ALPINE_BASE: alpine:3.21.3
|
||||
CDN_DESTINATION:
|
||||
from_secret: rgm_cdn_destination
|
||||
DESTINATION:
|
||||
@@ -4567,7 +4567,7 @@ steps:
|
||||
environment:
|
||||
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
|
||||
from_secret: dagger_token
|
||||
ALPINE_BASE: alpine:3.20.6
|
||||
ALPINE_BASE: alpine:3.21.3
|
||||
CDN_DESTINATION:
|
||||
from_secret: rgm_cdn_destination
|
||||
DESTINATION:
|
||||
@@ -4695,7 +4695,7 @@ steps:
|
||||
environment:
|
||||
_EXPERIMENTAL_DAGGER_CLOUD_TOKEN:
|
||||
from_secret: dagger_token
|
||||
ALPINE_BASE: alpine:3.20.6
|
||||
ALPINE_BASE: alpine:3.21.3
|
||||
CDN_DESTINATION:
|
||||
from_secret: rgm_cdn_destination
|
||||
DESTINATION:
|
||||
@@ -4838,7 +4838,7 @@ steps:
|
||||
name: grabpl
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
image: alpine:3.20.6
|
||||
image: alpine:3.21.3
|
||||
name: identify-runner
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -5262,7 +5262,7 @@ steps:
|
||||
- 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
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana-ci-deploy:1.3.3
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine:3.20.6
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine:3.21.3
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM ubuntu:22.04
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM byrnedo/alpine-curl:0.1.8
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM plugins/slack
|
||||
@@ -5300,7 +5300,7 @@ steps:
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL node:22-bookworm
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL google/cloud-sdk:431.0.0
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana-ci-deploy:1.3.3
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL alpine:3.20.6
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL alpine:3.21.3
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL ubuntu:22.04
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL byrnedo/alpine-curl:0.1.8
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL plugins/slack
|
||||
@@ -5564,6 +5564,6 @@ kind: secret
|
||||
name: gcr_credentials
|
||||
---
|
||||
kind: signature
|
||||
hmac: 558d477c002eb799c23f6631aafc7df933518e445e59f34ceb989e73f4dc60bc
|
||||
hmac: f16a4715c7a4e6a4ffb1fe041b42fb966310fd5da455239614e9a239493aff82
|
||||
|
||||
...
|
||||
|
||||
@@ -776,6 +776,7 @@ embed.go @grafana/grafana-as-code
|
||||
/.github/workflows/doc-validator.yml @grafana/docs-tooling
|
||||
/.github/workflows/deploy-pr-preview.yml @grafana/docs-tooling
|
||||
/.github/workflows/epic-add-to-platform-ux-parent-project.yml @meanmina
|
||||
/.github/workflows/feature-toggles-ci.yml @grafana/docs-tooling
|
||||
/.github/workflows/github-release.yml @grafana/grafana-developer-enablement-squad
|
||||
/.github/workflows/issue-opened.yml @grafana/grafana-community-support
|
||||
/.github/workflows/metrics-collector.yml @torkelo
|
||||
|
||||
@@ -640,7 +640,7 @@
|
||||
"name": "area/configuration",
|
||||
"action": "addToProject",
|
||||
"addToProject": {
|
||||
"url": "https://github.com/orgs/grafana/projects/96"
|
||||
"url": "https://github.com/orgs/grafana/projects/665"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -744,7 +744,7 @@
|
||||
"name": "area/backend/db/postgres",
|
||||
"action": "addToProject",
|
||||
"addToProject": {
|
||||
"url": "https://github.com/orgs/grafana/projects/96"
|
||||
"url": "https://github.com/orgs/grafana/projects/835"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -93,8 +94,8 @@ jobs:
|
||||
uses: grafana/shared-workflows/actions/get-vault-secrets@28361cdb22223e5f1e34358c86c20908e7248760 # 1.1.0
|
||||
with:
|
||||
repo_secrets: |
|
||||
GITHUB_APP_ID=github-app:app-id
|
||||
GITHUB_APP_PRIVATE_KEY=github-app:private-key
|
||||
GITHUB_APP_ID=alerting-team:app-id
|
||||
GITHUB_APP_PRIVATE_KEY=alerting-team:private-key
|
||||
|
||||
- name: "Generate token"
|
||||
id: generate_token
|
||||
@@ -127,4 +128,4 @@ jobs:
|
||||
if: steps.create-pr.outputs.pull-request-url != ''
|
||||
run: |
|
||||
echo "## Pull Request Created" >> $GITHUB_STEP_SUMMARY
|
||||
echo "🔗 [View Pull Request](${{ steps.create-pr.outputs.pull-request-url }})" >> $GITHUB_STEP_SUMMARY
|
||||
echo "🔗 [View Pull Request](${{ steps.create-pr.outputs.pull-request-url }})" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Feature toggles CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'pkg/services/featuremgmt/toggles_gen_test.go'
|
||||
- 'pkg/services/featuremgmt/registry.go'
|
||||
- 'docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: 'go.mod'
|
||||
cache: true
|
||||
|
||||
- name: Run feature toggle tests
|
||||
run: go test -v -run TestFeatureToggleFiles ./pkg/services/featuremgmt/
|
||||
@@ -113,6 +113,7 @@ profile.cov
|
||||
/pkg/extensions/*
|
||||
!/pkg/extensions/.keep
|
||||
!/pkg/extensions/main.go
|
||||
!/pkg/extensions/enterprise_imports.go
|
||||
/public/app/extensions
|
||||
!/public/app/extensions/.keep
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
# to maintain formatting of multiline commands in vscode, add the following to settings.json:
|
||||
# "docker.languageserver.formatter.ignoreMultilineInstructions": true
|
||||
|
||||
ARG BASE_IMAGE=alpine:3.20
|
||||
ARG BASE_IMAGE=alpine:3.21
|
||||
ARG JS_IMAGE=node:22-alpine
|
||||
ARG JS_PLATFORM=linux/amd64
|
||||
ARG GO_IMAGE=golang:1.23.5-alpine
|
||||
|
||||
@@ -32,7 +32,7 @@ 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.6.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
@@ -83,7 +83,7 @@ require (
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -60,8 +60,8 @@ github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -269,8 +269,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -27,7 +27,7 @@ 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.6.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
@@ -73,7 +73,7 @@ require (
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.32.1 // indirect
|
||||
|
||||
@@ -40,8 +40,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -195,8 +195,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -28,7 +28,7 @@ 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.6.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
@@ -74,7 +74,7 @@ require (
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.32.1 // indirect
|
||||
|
||||
@@ -40,8 +40,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -195,8 +195,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -136,6 +136,14 @@ datasources:
|
||||
tsdbResolution: 1
|
||||
tsdbVersion: 3
|
||||
|
||||
- name: gdev-opentsdb-v2.4
|
||||
type: opentsdb
|
||||
access: proxy
|
||||
url: http://localhost:4242
|
||||
jsonData:
|
||||
tsdbResolution: 1
|
||||
tsdbVersion: 4
|
||||
|
||||
- name: gdev-elasticsearch
|
||||
type: elasticsearch
|
||||
uid: gdev-elasticsearch
|
||||
|
||||
@@ -62,7 +62,7 @@ To configure basic settings for the data source, complete the following steps:
|
||||
| **Default** | Default data source that will be be pre-selected for new panels. |
|
||||
| **URL** | The HTTP protocol, IP, and port of your OpenTSDB server (default port is usually 4242). |
|
||||
| **Allowed cookies** | Listing of cookies to forward to the data source. |
|
||||
| **Version** | The OpenTSDB version. |
|
||||
| **Version** | The OpenTSDB version (supported versions are: 2.4, 2.3, 2.2 and versions less than 2.1). |
|
||||
| **Resolution** | Metrics from OpenTSDB may have data points with either second or millisecond resolution. |
|
||||
| **Lookup limit** | Default is 1000. |
|
||||
|
||||
@@ -98,9 +98,13 @@ can be used to query OpenTSDB. Fill Policy is also introduced in OpenTSDB 2.2.
|
||||
While using OpenTSDB 2.2 data source, make sure you use either Filters or Tags as they are mutually exclusive. If used together, might give you weird results.
|
||||
{{% /admonition %}}
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
When using OpenTSDB 2.4 with alerting, queries are executed with the parameter `arrays=true`. This causes OpenTSDB to return data points as an array of arrays instead of a map of key-value pairs. Grafana then converts this data into the appropriate data frame format.
|
||||
{{% /admonition %}}
|
||||
|
||||
### Auto complete suggestions
|
||||
|
||||
As soon as you start typing metric names, tag names and tag values , you should see highlighted auto complete suggestions for them.
|
||||
As you begin typing metric names, tag names, or tag values, highlighted autocomplete suggestions will appear.
|
||||
The autocomplete only works if the OpenTSDB suggest API is enabled.
|
||||
|
||||
## Templating queries
|
||||
|
||||
@@ -55,7 +55,7 @@ To add the Prometheus data source, complete the following steps:
|
||||
1. Click **Connections** in the left-side menu.
|
||||
1. Under **Connections**, click **Add new connection**.
|
||||
1. Enter `Prometheus` in the search bar.
|
||||
1. Select **Prometheus**.
|
||||
1. Click **Prometheus data source**.
|
||||
1. Click **Add new data source** in the upper right.
|
||||
1. Enter a name for the data source.
|
||||
|
||||
|
||||
@@ -18,11 +18,16 @@ labels:
|
||||
- cloud
|
||||
- enterprise
|
||||
- oss
|
||||
menuTitle: Configure data links
|
||||
title: Configure data links
|
||||
menuTitle: Configure data links and actions
|
||||
title: Configure data links and actions
|
||||
description: Configure data links to create links between dashboards and link to external resources
|
||||
weight: 80
|
||||
refs:
|
||||
api-settings:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/panels-visualizations/visualizations/canvas/#button-api-options
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana/latest/panels-visualizations/visualizations/canvas/#button-api-options
|
||||
global-variables:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/dashboards/variables/add-template-variables/#__from-and-__to
|
||||
@@ -125,9 +130,14 @@ refs:
|
||||
destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/bar-chart/
|
||||
---
|
||||
|
||||
# Configure data links
|
||||
# Configure data links and actions
|
||||
|
||||
Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel. You can create links that include the series name or even the value under the cursor. For example, if your visualization shows four servers, you can add a data link to one or two of them.
|
||||
_Data links_ allow you to link to other panels, dashboards, and external resources and _actions_ let you trigger basic, unauthenticated, API calls.
|
||||
In both cases, you can carry out these tasks while maintaining the context of the source panel.
|
||||
|
||||
## Data links
|
||||
|
||||
With data links, you can create links that include the series name or even the value under the cursor. For example, if your visualization shows four servers, you can add a data link to one or two of them.
|
||||
|
||||
The link itself is accessible in different ways depending on the visualization. For the time series visualization you need to click a data point or line:
|
||||
|
||||
@@ -139,7 +149,7 @@ For visualizations like stat, gauge, or bar gauge you can click anywhere on the
|
||||
|
||||
If there's only one data link in the visualization, clicking anywhere on the visualization opens the link rather than the context menu.
|
||||
|
||||
## Supported visualizations
|
||||
### Supported visualizations
|
||||
|
||||
You can configure data links for the following visualizations:
|
||||
|
||||
@@ -164,11 +174,32 @@ You can configure data links for the following visualizations:
|
||||
|
||||
{{< /column-list >}}
|
||||
|
||||
## Data link variables
|
||||
## Actions
|
||||
|
||||
Variables in data links let you send people to a detailed dashboard with preserved data filters. For example, you could use variables to specify a label, time range, series, or variable selection.
|
||||
Using actions, you can trigger processes like starting or shutting down a server, directly from a dashboard panel. [API settings](ref:api-settings) are configured in the **Add action** dialog box. You can also pass variables in the API editor.
|
||||
|
||||
To see a list of available variables, enter `$` in the data link **URL** field.
|
||||
### Supported visualizations
|
||||
|
||||
You can configure actions for the following visualizations:
|
||||
|
||||
{{< column-list >}}
|
||||
|
||||
- [Bar chart](ref:bar-chart)
|
||||
- [Candlestick](ref:candlestick)
|
||||
- [State timeline](ref:state-timeline)
|
||||
- [Status history](ref:status-history)
|
||||
- [Table](ref:table)
|
||||
- [Time series](ref:time-series)
|
||||
- [Trend](ref:trend)
|
||||
- [XY chart](ref:xy-chart)
|
||||
|
||||
{{< /column-list >}}
|
||||
|
||||
## Data link and action variables {#data-link-variables}
|
||||
|
||||
Variables in data links and actions let you send people to a detailed dashboard or trigger an API call with preserved data filters. For example, you could use variables to specify a label, time range, series, or variable selection.
|
||||
|
||||
To see a list of available variables, enter `$` in the data link or action **URL** field.
|
||||
|
||||
{{% admonition type="note" %}}
|
||||
These variables changed in 6.4 so if you have an older version of Grafana, then use the version picker to select docs for an older version of Grafana.
|
||||
@@ -176,11 +207,11 @@ These variables changed in 6.4 so if you have an older version of Grafana, then
|
||||
|
||||
Azure Monitor, [CloudWatch](ref:cloudwatch), and [Google Cloud Monitoring](ref:google-cloud-monitoring) have pre-configured data links called _deep links_.
|
||||
|
||||
You can also use template variables in your data links URLs. For more information, refer to [Templates and variables](ref:templates-and-variables).
|
||||
You can also use template variables in your data links or actions URLs. For more information, refer to [Templates and variables](ref:templates-and-variables).
|
||||
|
||||
### Time range panel variables
|
||||
|
||||
These variables allow you to include the current time range in the data link URL:
|
||||
These variables allow you to include the current time range in the data link or action URL:
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------ | ------------------------------------------------------------------------ |
|
||||
@@ -188,7 +219,7 @@ These variables allow you to include the current time range in the data link URL
|
||||
| `__from` | For more information, refer to [Global variables](ref:global-variables). |
|
||||
| `__to` | For more information, refer to [Global variables](ref:global-variables). |
|
||||
|
||||
When you create data links using time range variables like `__url_time_range` in the URL, you have to form the query parameter syntax yourself; that is, you must format the URL by appending query parameters using the question mark (`?`) and ampersand (`&`) syntax. These characters aren't automatically generated.
|
||||
When you create data links and actions using time range variables like `__url_time_range` in the URL, you have to form the query parameter syntax yourself; that is, you must format the URL by appending query parameters using the question mark (`?`) and ampersand (`&`) syntax. These characters aren't automatically generated.
|
||||
|
||||
### Series variables
|
||||
|
||||
@@ -219,9 +250,9 @@ Value-specific variables are available under `__value` namespace:
|
||||
| `__value.text` | Text representation of a value |
|
||||
| `__value.calc` | Calculation name if the value is result of calculation |
|
||||
|
||||
Using value-specific variables in data links can show different results depending on the set option of Tooltip mode.
|
||||
Using value-specific variables in data links and actions can show different results depending on the set option of Tooltip mode.
|
||||
|
||||
When you create data links using time range variables like `__value.time` in the URL, you have to form the query parameter syntax yourself; that is, you must add the question mark (`?`) and ampersand (`&`). These characters aren't automatically generated.
|
||||
When you create data links and actions using time range variables like `__value.time` in the URL, you have to form the query parameter syntax yourself; that is, you must add the question mark (`?`) and ampersand (`&`). These characters aren't automatically generated.
|
||||
|
||||
### Data variables
|
||||
|
||||
@@ -247,20 +278,29 @@ When linking to another dashboard that uses template variables, select variable
|
||||
|
||||
If you want to add all of the current dashboard's variables to the URL, then use `${__all_variables}`.
|
||||
|
||||
## Add a data link
|
||||
## Add data links or actions {#add-a-data-link}
|
||||
|
||||
The following tasks describe how to configure data links and actions.
|
||||
|
||||
{{< tabs >}}
|
||||
{{< tab-content name="Add data links" >}}
|
||||
To add a data link, follow these steps:
|
||||
|
||||
1. Navigate to the panel to which you want to add the data link.
|
||||
1. Hover over any part of the panel to display the menu icon in the upper-right corner.
|
||||
1. Click the menu icon and select **Edit** to open the panel editor.
|
||||
1. In the panel edit pane, scroll down to the **Data links** section and expand it.
|
||||
1. Scroll down to the **Data links and actions** section and expand it.
|
||||
1. Click **+ Add link**.
|
||||
1. In the dialog box that opens, enter a **Title**. This is a human-readable label for the link displayed in the UI. This is a required field.
|
||||
1. Enter the **URL** or variable to which you want to link. This is a required field.
|
||||
1. In the dialog box that opens, enter a **Title**.
|
||||
|
||||
To add a data link variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables.
|
||||
This is a human-readable label for the link displayed in the UI. This is a required field.
|
||||
|
||||
1. Enter the **URL** to which you want to link.
|
||||
|
||||
To add a data link variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. This is a required field.
|
||||
|
||||
1. If you want the link to open in a new tab, toggle the **Open in a new tab** switch.
|
||||
1. If you want the data link to open with a single click, toggle the **One click** switch.
|
||||
1. If you want the data link to open with a single click on the visualization, toggle the **One click** switch.
|
||||
|
||||
Only one data link can have **One click** enabled at a time. **One click** is only supported for some visualizations.
|
||||
|
||||
@@ -268,4 +308,37 @@ If you want to add all of the current dashboard's variables to the URL, then use
|
||||
1. Click **Save dashboard**.
|
||||
1. Click **Back to dashboard** and then **Exit edit**.
|
||||
|
||||
If you add multiple data links, you can control the order in which they appear in the visualization. To do this, click and drag the data link to the desired position.
|
||||
{{< /tab-content >}}
|
||||
{{< tab-content name="Add actions" >}}
|
||||
|
||||
{{< admonition type="note">}}
|
||||
Actions are not supported for all visualizations. For the list of supported visualizations, refer to [Supported visualizations](#supported-visualizations-1).
|
||||
{{< /admonition >}}
|
||||
|
||||
To add an action, by follow these steps:
|
||||
|
||||
1. Navigate to the panel to which you want to add the action.
|
||||
1. Hover over any part of the panel to display the menu icon in the upper-right corner.
|
||||
1. Click the menu icon and select **Edit** to open the panel editor.
|
||||
1. Scroll down to the **Data links and actions** section and expand it.
|
||||
1. Click **+ Add action**.
|
||||
1. In the dialog box that opens, define the API call settings:
|
||||
|
||||
| Option | Description |
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Title | A human-readable label for the action that's displayed in the UI. |
|
||||
| Confirmation message | A descriptive prompt to confirm or cancel the action. |
|
||||
| Method | Select from **POST**, **PUT**, or **GET**. |
|
||||
| URL | The request URL.</p><p>To add a variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. |
|
||||
| Query parameters | **Key** and **Value** pairs. Click the **+** icon to add as many key/value pairs as you need. |
|
||||
| Headers | Comprised of **Key** and **Value** pairs and a **Content-Type**.</p><p>Click the **+** icon to add as many key/value pairs as you need. |
|
||||
| Content-Type | Select from the following: **application/json**, **text/plain**, **application/XML**, and **application/x-www-form-urlencoded**. |
|
||||
| Body | The body of the request. |
|
||||
|
||||
1. Click **Save** to save changes and close the dialog box.
|
||||
1. Click **Save dashboard**.
|
||||
1. Click **Back to dashboard** and then **Exit edit**.
|
||||
{{< /tab-content >}}
|
||||
{{< /tabs >}}
|
||||
|
||||
If you add multiple data links or actions, you can control the order in which they appear in the visualization. To do this, click and drag the data link or action to the desired position.
|
||||
|
||||
@@ -199,7 +199,7 @@ You can set standard min/max options to define hard limits of the Y-axis. For mo
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ This option only applies when bar size is set to manual.
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
## Data links
|
||||
## Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ The candlestick visualization is based on the time series visualization. It can
|
||||
|
||||
{{< docs/shared lookup="visualizations/tooltip-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
## Data links
|
||||
## Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ Adjust the sizes of the gauge text.
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -711,7 +711,7 @@ Displays debug information in the upper right corner. This can be useful for deb
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ Choose whether you want to display the heatmap legend on the visualization by to
|
||||
|
||||
Set the color used to show exemplar data.
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ Choose from the following:
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
## Data links
|
||||
## Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ Use these settings to define how the legend appears in your visualization. For m
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ Adjust the sizes of the gauge text.
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ The **Page size** option lets you paginate the state timeline visualization to l
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ Controls the opacity of state regions.
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
## Data links
|
||||
## Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -246,6 +246,7 @@ If you want to apply a cell type to only some fields instead of all fields, you
|
||||
| Data links | If you've configured data links, when the cell type is **Auto**, the cell text becomes clickable. If you change the cell type to **Data links**, the cell text reflects the titles of the configured data links. To control the application of data link text more granularly, use a **Cell option > Cell type > Data links** field override. |
|
||||
| [JSON View](#json-view) | Shows values formatted as code. |
|
||||
| [Image](#image) | If the field value is an image URL or a base64 encoded image, the table displays the image. |
|
||||
| [Actions](#actions) | The cell displays a button that triggers a basic, unauthenticated API call when clicked. |
|
||||
|
||||
##### Sparkline
|
||||
|
||||
@@ -333,6 +334,23 @@ Set the following options:
|
||||
- **Alt text** - Set the alternative text of an image. The text will be available for screen readers and in cases when images can't be loaded.
|
||||
- **Title text** - Set the text that's displayed when the image is hovered over with a cursor.
|
||||
|
||||
##### Actions
|
||||
|
||||
The cell displays a button that triggers a basic, unauthenticated API call when clicked.
|
||||
Configure the API call with the following options:
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| Option | Description |
|
||||
| ------- | ------------ |
|
||||
| Endpoint | Enter the endpoint URL. |
|
||||
| Method | Choose from **GET**, **POST**, and **PUT**. |
|
||||
| Content-Type | Select an option in the drop-down list. Choose from: JSON, Text, JavaScript, HTML, XML, and x-www-form-urlencoded. |
|
||||
| Query parameters | Enter as many **Key**, **Value** pairs as you need. |
|
||||
| Header parameters | Enter as many **Key**, **Value** pairs as you need. |
|
||||
| Payload | Enter the body of the API call. |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
#### Wrap text
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
@@ -362,9 +380,9 @@ If you want to apply this setting to only some fields instead of all fields, you
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
{{< docs/shared lookup="visualizations/datalink-options-3.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Value mappings
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ Set the position of the bar relative to a data point. In the examples below, **S
|
||||
|
||||
{{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
### Data links
|
||||
### Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ For example, you could represent engine power and torque versus speed where spee
|
||||
|
||||
{{< docs/shared lookup="visualizations/tooltip-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
## Data links
|
||||
## Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -308,7 +308,7 @@ You can customize the following standard options:
|
||||
|
||||
To learn more, refer to [Configure standard options](ref:configure-standard-options).
|
||||
|
||||
## Data links
|
||||
## Data links and actions
|
||||
|
||||
{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="<GRAFANA_VERSION>" >}}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
|
||||
| `featureHighlights` | Highlight Grafana Enterprise features | |
|
||||
| `correlations` | Correlations page | Yes |
|
||||
| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes |
|
||||
| `accessControlOnCall` | Access control primitives for OnCall | Yes |
|
||||
| `nestedFolders` | Enable folder nesting | Yes |
|
||||
| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes |
|
||||
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes |
|
||||
@@ -131,7 +130,6 @@ Experimental features might be changed or removed without prior notice.
|
||||
| `lokiExperimentalStreaming` | Support new streaming approach for loki (prototype, needs special loki build) |
|
||||
| `storage` | Configurable storage for dashboards, datasources, and resources |
|
||||
| `canvasPanelNesting` | Allow elements nesting |
|
||||
| `vizActions` | Allow actions in visualizations |
|
||||
| `disableSecretsCompatibility` | Disable duplicated secret storage in legacy tables |
|
||||
| `logRequestsInstrumentedAsUnknown` | Logs the path for requests that are instrumented as unknown |
|
||||
| `showDashboardValidationWarnings` | Show warnings when dashboards do not validate against the schema |
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
---
|
||||
title: Data link options
|
||||
title: Data links and actions options
|
||||
comments: |
|
||||
This file is used in the following visualizations: bar gauge, gauge, pie chart, stat, table
|
||||
This file is used in the following visualizations: bar gauge, gauge, pie chart, stat
|
||||
---
|
||||
|
||||
Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel.
|
||||
You can create links that include the series name or even the value under the cursor.
|
||||
To learn more, refer to [Configure data links](../../configure-data-links/).
|
||||
To learn more, refer to [Configure data links and actions](../../configure-data-links/).
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Actions are not supported for this visualization.
|
||||
{{< /admonition >}}
|
||||
|
||||
For each data link, set the following options:
|
||||
|
||||
@@ -14,4 +18,5 @@ For each data link, set the following options:
|
||||
- **URL**
|
||||
- **Open in new tab**
|
||||
|
||||
Data links for this visualization don't include the **One click** switch, however, if there's only one data link configured, that data link has single-click functionality. If multiple data links are configured, then clicking the visualization opens a menu that displays all the data links.
|
||||
Data links for this visualization don't include the **One click** switch, however, if there's only one data link configured, that data link has single-click functionality.
|
||||
If multiple data links are configured, then clicking the visualization opens a menu that displays all the data links.
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
---
|
||||
title: Data link options
|
||||
title: Data links and actions options
|
||||
comments: |
|
||||
This file is used in the following visualizations: bar chart, candlestick, state timeline, status history, time series, trend, xy chart
|
||||
---
|
||||
|
||||
Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel. You can create links that include the series name or even the value under the cursor.
|
||||
_Data links_ allow you to link to other panels, dashboards, and external resources and _actions_ let you trigger basic, unauthenticated, API calls.
|
||||
In both cases, you can carry out these tasks while maintaining the context of the source panel.
|
||||
|
||||
For each data link, set the following options:
|
||||
|
||||
@@ -13,4 +14,21 @@ For each data link, set the following options:
|
||||
- **Open in new tab**
|
||||
- **One click** - Opens the data link with a single click. Only one data link can have **One click** enabled at a time.
|
||||
|
||||
To learn more, refer to [Configure data links](../../configure-data-links/).
|
||||
For each action, define the following API call settings:
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|
||||
| Option | Description |
|
||||
| -------------------- | ----------------------------------------------------------------- |
|
||||
| Title | A human-readable label for the action that's displayed in the UI. |
|
||||
| Confirmation message | A descriptive prompt to confirm or cancel the action. |
|
||||
| Method | Select from **POST**, **PUT**, or **GET**. |
|
||||
| URL | The request URL.</p><p>To add a variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. |
|
||||
| Query parameters | **Key** and **Value** pairs. Click the **+** icon to add as many key/value pairs as you need. |
|
||||
| Headers | Comprised of **Key** and **Value** pairs and a **Content-Type**.</p><p>Click the **+** icon to add as many key/value pairs as you need. |
|
||||
| Content-Type | Select from the following: **application/json**, **text/plain**, **application/XML**, and **application/x-www-form-urlencoded**. |
|
||||
| Body | The body of the request. |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
To learn more, refer to [Configure data links and actions](../../configure-data-links/).
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: Data links and actions options
|
||||
comments: |
|
||||
This file is used in the following visualizations: table
|
||||
---
|
||||
|
||||
_Data links_ allow you to link to other panels, dashboards, and external resources and _actions_ let you trigger basic, unauthenticated, API calls.
|
||||
In both cases, you can carry out these tasks while maintaining the context of the source panel.
|
||||
|
||||
For each data link, set the following options:
|
||||
|
||||
- **Title**
|
||||
- **URL**
|
||||
- **Open in new tab**
|
||||
|
||||
Data links for this visualization don't include the **One click** switch, however, if there's only one data link configured, that data link has single-click functionality.
|
||||
If multiple data links are configured, then clicking the visualization opens a menu that displays all the data links.
|
||||
|
||||
For each action, define the following API call settings:
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|
||||
| Option | Description |
|
||||
| -------------------- | ----------------------------------------------------------------- |
|
||||
| Title | A human-readable label for the action that's displayed in the UI. |
|
||||
| Confirmation message | A descriptive prompt to confirm or cancel the action. |
|
||||
| Method | Select from **POST**, **PUT**, or **GET**. |
|
||||
| URL | The request URL.</p><p>To add a variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. |
|
||||
| Query parameters | **Key** and **Value** pairs. Click the **+** icon to add as many key/value pairs as you need. |
|
||||
| Headers | Comprised of **Key** and **Value** pairs and a **Content-Type**.</p><p>Click the **+** icon to add as many key/value pairs as you need. |
|
||||
| Content-Type | Select from the following: **application/json**, **text/plain**, **application/XML**, and **application/x-www-form-urlencoded**. |
|
||||
| Body | The body of the request. |
|
||||
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
To learn more, refer to [Configure data links and actions](../../configure-data-links/).
|
||||
@@ -1,10 +1,15 @@
|
||||
---
|
||||
title: Data link options
|
||||
title: Data links and actions options
|
||||
comments: |
|
||||
This file is used in the following visualizations: geomap, heatmap, histogram
|
||||
---
|
||||
|
||||
Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel. You can create links that include the series name or even the value under the cursor.
|
||||
Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel.
|
||||
You can create links that include the series name or even the value under the cursor.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Actions are not supported for this visualization.
|
||||
{{< /admonition >}}
|
||||
|
||||
For each data link, set the following options:
|
||||
|
||||
@@ -12,4 +17,4 @@ For each data link, set the following options:
|
||||
- **URL**
|
||||
- **Open in new tab**
|
||||
|
||||
To learn more, refer to [Configure data links](../../configure-data-links/).
|
||||
To learn more, refer to [Configure data links and actions](../../configure-data-links/).
|
||||
|
||||
@@ -6,6 +6,7 @@ require (
|
||||
buf.build/gen/go/parca-dev/parca/connectrpc/go v1.17.0-20240902100956-02fd72488966.1 // @grafana/observability-traces-and-profiling
|
||||
buf.build/gen/go/parca-dev/parca/protocolbuffers/go v1.34.2-20240902100956-02fd72488966.2 // @grafana/observability-traces-and-profiling
|
||||
cloud.google.com/go/kms v1.20.0 // @grafana/grafana-backend-group
|
||||
cloud.google.com/go/spanner v1.70.0 // @grafana/grafana-search-and-storage
|
||||
cloud.google.com/go/storage v1.43.0 // @grafana/grafana-backend-group
|
||||
connectrpc.com/connect v1.17.0 // @grafana/observability-traces-and-profiling
|
||||
cuelang.org/go v0.11.1 // @grafana/grafana-as-code
|
||||
@@ -64,7 +65,7 @@ require (
|
||||
github.com/golang/mock v1.7.0-rc.1 // @grafana/alerting-backend
|
||||
github.com/golang/protobuf v1.5.4 // @grafana/grafana-backend-group
|
||||
github.com/golang/snappy v0.0.4 // @grafana/alerting-backend
|
||||
github.com/google/go-cmp v0.6.0 // @grafana/grafana-backend-group
|
||||
github.com/google/go-cmp v0.7.0 // @grafana/grafana-backend-group
|
||||
github.com/google/go-querystring v1.1.0 // indirect; @grafana/oss-big-tent
|
||||
github.com/google/uuid v1.6.0 // @grafana/grafana-backend-group
|
||||
github.com/google/wire v0.6.0 // @grafana/grafana-backend-group
|
||||
@@ -72,8 +73,8 @@ require (
|
||||
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-20250224133628-2acbeef29642 // @grafana/alerting-backend
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 // @grafana/identity-access-team
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 // @grafana/identity-access-team
|
||||
github.com/grafana/authlib v0.0.0-20250225105729-99e678595501 // @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
|
||||
github.com/grafana/dataplane/sdata v0.0.9 // @grafana/observability-metrics
|
||||
github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 // @grafana/grafana-backend-group
|
||||
@@ -87,7 +88,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.266.0 // @grafana/plugins-platform-backend
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.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
|
||||
@@ -179,7 +180,7 @@ require (
|
||||
gonum.org/v1/gonum v0.15.1 // @grafana/oss-big-tent
|
||||
google.golang.org/api v0.216.0 // @grafana/grafana-backend-group
|
||||
google.golang.org/grpc v1.70.0 // @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.36.4 // @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.36.5 // @grafana/plugins-platform-backend
|
||||
gopkg.in/ini.v1 v1.67.0 // @grafana/alerting-backend
|
||||
gopkg.in/mail.v2 v2.3.1 // @grafana/grafana-backend-group
|
||||
gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-backend
|
||||
@@ -226,6 +227,7 @@ require (
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/iam v1.2.1 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.1 // indirect
|
||||
cloud.google.com/go/monitoring v1.21.1 // indirect
|
||||
cuelabs.dev/go/oci/ociregistry v0.0.0-20240906074133-82eb438dd565 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
|
||||
@@ -241,6 +243,8 @@ require (
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect
|
||||
github.com/FZambia/eagle v0.1.0 // indirect
|
||||
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
@@ -304,12 +308,14 @@ require (
|
||||
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 // indirect
|
||||
github.com/caio/go-tdigest v3.1.0+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/centrifugal/protocol v0.13.4 // indirect
|
||||
github.com/cespare/xxhash v1.1.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cheekybits/genny v1.0.0 // indirect
|
||||
github.com/chromedp/cdproto v0.0.0-20240810084448-b931b754e476 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect
|
||||
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
@@ -325,10 +331,11 @@ 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.0 // indirect
|
||||
github.com/elazarl/goproxy v1.7.1 // 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
|
||||
github.com/envoyproxy/go-control-plane v0.13.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
|
||||
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
@@ -512,9 +519,11 @@ require (
|
||||
go.mongodb.org/mongo-driver v1.16.1 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.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/metric v1.32.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
|
||||
|
||||
@@ -187,6 +187,7 @@ cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvj
|
||||
cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA=
|
||||
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
|
||||
cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=
|
||||
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
|
||||
cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI=
|
||||
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||
cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=
|
||||
@@ -390,6 +391,8 @@ cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhI
|
||||
cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4=
|
||||
cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w=
|
||||
cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=
|
||||
cloud.google.com/go/monitoring v1.21.1 h1:zWtbIoBMnU5LP9A/fz8LmWMGHpk4skdfeiaa66QdFGc=
|
||||
cloud.google.com/go/monitoring v1.21.1/go.mod h1:Rj++LKrlht9uBi8+Eb530dIrzG/cU/lB8mt+lbeFK1c=
|
||||
cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=
|
||||
cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=
|
||||
cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM=
|
||||
@@ -536,6 +539,8 @@ cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+
|
||||
cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos=
|
||||
cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk=
|
||||
cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M=
|
||||
cloud.google.com/go/spanner v1.70.0 h1:nj6p/GJTgMDiSQ1gQ034ItsKuJgHiMOjtOlONOg8PSo=
|
||||
cloud.google.com/go/spanner v1.70.0/go.mod h1:X5T0XftydYp0K1adeJQDJtdWpbrOeJ7wHecM4tK6FiE=
|
||||
cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=
|
||||
cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=
|
||||
cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0=
|
||||
@@ -706,6 +711,10 @@ github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/FZambia/eagle v0.1.0 h1:9gyX6x+xjoIfglgyPTcYm7dvY7FJ93us1QY5De4CyXA=
|
||||
github.com/FZambia/eagle v0.1.0/go.mod h1:YjGSPVkQTNcVLfzEUQJNgW9ScPR0K4u/Ky0yeFa4oDA=
|
||||
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 h1:oVLqHXhnYtUwM89y9T1fXGaK9wTkXHgNp8/ZNMQzUxE=
|
||||
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
|
||||
@@ -954,6 +963,7 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/centrifugal/centrifuge v0.33.3 h1:uyqBc27oM+qnC3NX5imvZxuk9+u2ze6QGWHDICZeoSc=
|
||||
github.com/centrifugal/centrifuge v0.33.3/go.mod h1:GaOF4CiREY5x6lW7zYUz46Qrc6aUZ6J/AMV/kROc2+U=
|
||||
@@ -992,6 +1002,7 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
|
||||
github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
@@ -1083,8 +1094,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.0 h1:EXv2nV4EjM60ZtsEVLYJG4oBXhDGutMKperpHsZ/v+0=
|
||||
github.com/elazarl/goproxy v1.7.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ=
|
||||
github.com/elazarl/goproxy v1.7.1 h1:1P7LPSxbqtNxusFnXclj6O56pjfq1xOQZ6a0mwwKUlY=
|
||||
github.com/elazarl/goproxy v1.7.1/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=
|
||||
@@ -1103,12 +1114,14 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
|
||||
github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI=
|
||||
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=
|
||||
github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
|
||||
github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
@@ -1409,8 +1422,9 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
@@ -1513,10 +1527,10 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/alerting v0.0.0-20250224133628-2acbeef29642 h1:iQ0h/h+QoguSZDF+ZpPxcM/C+m1kjh+aXjMpxywowPA=
|
||||
github.com/grafana/alerting v0.0.0-20250224133628-2acbeef29642/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 h1:NTMmow+74I3Jb033xhbRgWQS7A//5TDhiM4tl7bsVP4=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7/go.mod h1:T3X4z0ejGfJOiOmZLFeKCRT/yxWJq/RtclAc/PHj/w4=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 h1:EokLC5grHwLPs4tXW8T6E8187H1e5G9AP0QQ5B60HbA=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/authlib v0.0.0-20250225105729-99e678595501 h1:FTuDRy/Shw8yOdG+v1DnkeuaCAl8fvwgcfaG9Wccuhg=
|
||||
github.com/grafana/authlib v0.0.0-20250225105729-99e678595501/go.mod h1:XVpdLhaeYqz414FmGnW00/0vTe1x8c0GRH3KaeRtyg0=
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 h1:DnRUYiAotHXnrfYJCvhH1NkiyWVcPm5Pd+P7Ugqt/d8=
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/dataplane/examples v0.0.1 h1:K9M5glueWyLoL4//H+EtTQq16lXuHLmOhb6DjSCahzA=
|
||||
github.com/grafana/dataplane/examples v0.0.1/go.mod h1:h5YwY8s407/17XF5/dS8XrUtsTVV2RnuW8+m1Mp46mg=
|
||||
github.com/grafana/dataplane/sdata v0.0.9 h1:AGL1LZnCUG4MnQtnWpBPbQ8ZpptaZs14w6kE/MWfg7s=
|
||||
@@ -1545,8 +1559,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.266.0 h1:YP+iEpXH3HRX9Xo4NHjsrJhN2W7uVTtkLNzMHYbmiLI=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.266.0/go.mod h1:bxkXrBQ4QSmOncsWdIOcpgP+M6wajQNMAPXlbWrqAWY=
|
||||
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/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=
|
||||
@@ -2316,6 +2330,7 @@ github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
@@ -2448,6 +2463,8 @@ 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/collector/pdata v1.22.0 h1:3yhjL46NLdTMoP8rkkcE9B0pzjf2973crn0KKhX5UrI=
|
||||
go.opentelemetry.io/collector/pdata v1.22.0/go.mod h1:nLLf6uDg8Kn5g3WNZwGyu8+kf77SwOqQvMTb5AXEbEY=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 h1:P78qWqkLSShicHmAzfECaTgvslqHxblNE9j62Ws1NK8=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0/go.mod h1:TVqo0Sda4Cv8gCIixd7LuLwW4EylumVWfhjZJjDD4DU=
|
||||
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=
|
||||
@@ -3314,9 +3331,11 @@ google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD
|
||||
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
|
||||
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
|
||||
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
||||
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
@@ -3339,8 +3358,8 @@ google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
|
||||
+3
-12
@@ -142,8 +142,6 @@ cloud.google.com/go/memcache v1.11.1 h1:2FGuyd3WY7buNDAkMBdmeIOheNWA3gwaXrttLrEd
|
||||
cloud.google.com/go/memcache v1.11.1/go.mod h1:3zF+dEqmEmElHuO4NtHiShekQY5okQtssjPBv7jpmZ8=
|
||||
cloud.google.com/go/metastore v1.14.1 h1:kGx+IUSSYCVn8LisCT4fpxCC9rauEVonzi7RlygdqWY=
|
||||
cloud.google.com/go/metastore v1.14.1/go.mod h1:WDvsAcbQLl9M4xL+eIpbKogH7aEaPWMhO9aRBcFOnJE=
|
||||
cloud.google.com/go/monitoring v1.21.1 h1:zWtbIoBMnU5LP9A/fz8LmWMGHpk4skdfeiaa66QdFGc=
|
||||
cloud.google.com/go/monitoring v1.21.1/go.mod h1:Rj++LKrlht9uBi8+Eb530dIrzG/cU/lB8mt+lbeFK1c=
|
||||
cloud.google.com/go/networkconnectivity v1.15.1 h1:EizN+cFGHzRAyiFTK8jT1PqTo+cSnbc2IGh6OmllS7Y=
|
||||
cloud.google.com/go/networkconnectivity v1.15.1/go.mod h1:tYAcT4Ahvq+BiePXL/slYipf/8FF0oNJw3MqFhBnSPI=
|
||||
cloud.google.com/go/networkmanagement v1.14.1 h1:0x3hVI6xbp3N/choffKPHMSxbzaPdHSD92cBElebXEk=
|
||||
@@ -204,8 +202,6 @@ cloud.google.com/go/servicemanagement v1.8.0 h1:fopAQI/IAzlxnVeiKn/8WiV6zKndjFkv
|
||||
cloud.google.com/go/serviceusage v1.6.0 h1:rXyq+0+RSIm3HFypctp7WoXxIA563rn206CfMWdqXX4=
|
||||
cloud.google.com/go/shell v1.8.1 h1:etoJal+LB7Pn8+5vE2aAh6QcFbBmerIOh5MxNDoXykw=
|
||||
cloud.google.com/go/shell v1.8.1/go.mod h1:jaU7OHeldDhTwgs3+clM0KYEDYnBAPevUI6wNLf7ycE=
|
||||
cloud.google.com/go/spanner v1.70.0 h1:nj6p/GJTgMDiSQ1gQ034ItsKuJgHiMOjtOlONOg8PSo=
|
||||
cloud.google.com/go/spanner v1.70.0/go.mod h1:X5T0XftydYp0K1adeJQDJtdWpbrOeJ7wHecM4tK6FiE=
|
||||
cloud.google.com/go/speech v1.25.1 h1:iGZJS3wrdkje/Vqiacx1+r+zVwUZoXVMdklYIVsvfNw=
|
||||
cloud.google.com/go/speech v1.25.1/go.mod h1:WgQghvghkZ1htG6BhYn98mP7Tg0mti8dBFDLMVXH/vM=
|
||||
cloud.google.com/go/storagetransfer v1.11.1 h1:Hd7H1zXGQGEWyWXxWVXDMuNCGasNQim1y9CIaMZIBX8=
|
||||
@@ -280,10 +276,6 @@ github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW5
|
||||
github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0=
|
||||
github.com/GoogleCloudPlatform/cloudsql-proxy v1.36.0 h1:kAtNAWwvTt5+iew6baV0kbOrtjYTXPtWNSyOFlcxkBU=
|
||||
github.com/GoogleCloudPlatform/cloudsql-proxy v1.36.0/go.mod h1:VRKXU8C7Y/aUKjRBTGfw0Ndv4YqNxlB8zAPJJDxbASE=
|
||||
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 h1:oVLqHXhnYtUwM89y9T1fXGaK9wTkXHgNp8/ZNMQzUxE=
|
||||
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM=
|
||||
github.com/IBM/go-sdk-core/v5 v5.17.4 h1:VGb9+mRrnS2HpHZFM5hy4J6ppIWnwNrw0G+tLSgcJLc=
|
||||
github.com/IBM/go-sdk-core/v5 v5.17.4/go.mod h1:KsAAI7eStAWwQa4F96MLy+whYSh39JzNjklZRbN/8ns=
|
||||
github.com/IBM/ibm-cos-sdk-go v1.11.0 h1:Jp55NLN3OvBwucMGpP5wNybyjncsmTZ9+GPHai/1cE8=
|
||||
@@ -387,7 +379,6 @@ github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9Mwe
|
||||
github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
|
||||
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
|
||||
@@ -510,6 +501,7 @@ github.com/elastic/go-sysinfo v1.11.2/go.mod h1:GKqR8bbMK/1ITnez9NIsIfXQr25aLhRJ
|
||||
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
|
||||
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
||||
github.com/elazarl/goproxy v1.3.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ=
|
||||
github.com/elazarl/goproxy v1.7.1 h1:1P7LPSxbqtNxusFnXclj6O56pjfq1xOQZ6a0mwwKUlY=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
@@ -593,6 +585,7 @@ github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs0
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-jsonnet v0.18.0 h1:/6pTy6g+Jh1a1I2UMoAODkqELFiVIdOxbNwv0DDzoOg=
|
||||
github.com/google/go-jsonnet v0.18.0/go.mod h1:C3fTzyVJDslXdiTqw/bTFk7vSGyCtH3MGRbDfvEwGd0=
|
||||
@@ -908,7 +901,6 @@ github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJ
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stoewer/parquet-cli v0.0.7 h1:rhdZODIbyMS3twr4OM3am8BPPT5pbfMcHLH93whDM5o=
|
||||
github.com/stoewer/parquet-cli v0.0.7/go.mod h1:bskxHdj8q3H1EmfuCqjViFoeO3NEvs5lzZAQvI8Nfjk=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/substrait-io/substrait v0.57.1 h1:GW8nnYfSowMseHR8Os82/X6lNtQGIK7p4p+lr6r+auw=
|
||||
github.com/substrait-io/substrait v0.57.1/go.mod h1:q9s+tjo+gK0lsA+SqYB0lhojNuxvdPdfYlGUP0hjbrA=
|
||||
github.com/substrait-io/substrait-go v1.2.0 h1:3ZNRkc8FYD7ifCagKEOZQtUcgMceMQfwo2N1NGaK4Q4=
|
||||
@@ -1056,8 +1048,6 @@ go.opentelemetry.io/contrib/bridges/prometheus v0.53.0 h1:BdkKDtcrHThgjcEia1737O
|
||||
go.opentelemetry.io/contrib/bridges/prometheus v0.53.0/go.mod h1:ZkhVxcJgeXlL/lVyT/vxNHVFiSG5qOaDwYaSgD8IfZo=
|
||||
go.opentelemetry.io/contrib/config v0.7.0 h1:b1rK5tGTuhhPirJiMxOcyQfZs76j2VapY6ODn3b2Dbs=
|
||||
go.opentelemetry.io/contrib/config v0.7.0/go.mod h1:8tdiFd8N5etOi3XzBmAoMxplEzI3TcL8dU5rM5/xcOQ=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 h1:P78qWqkLSShicHmAzfECaTgvslqHxblNE9j62Ws1NK8=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0/go.mod h1:TVqo0Sda4Cv8gCIixd7LuLwW4EylumVWfhjZJjDD4DU=
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.53.0 h1:13K+tY7E8GJInkrvRiPAhC0gi/7vKjzDNhtmCf+QXG8=
|
||||
go.opentelemetry.io/contrib/exporters/autoexport v0.53.0/go.mod h1:lyQF6xQ4iDnMg4sccNdFs1zf62xd79YI8vZqKjOTwMs=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74=
|
||||
@@ -1198,6 +1188,7 @@ google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojt
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
|
||||
@@ -36,14 +36,12 @@ export interface FeatureToggles {
|
||||
autoMigrateStatPanel?: boolean;
|
||||
disableAngular?: boolean;
|
||||
canvasPanelNesting?: boolean;
|
||||
vizActions?: boolean;
|
||||
disableSecretsCompatibility?: boolean;
|
||||
logRequestsInstrumentedAsUnknown?: boolean;
|
||||
grpcServer?: boolean;
|
||||
cloudWatchCrossAccountQuerying?: boolean;
|
||||
showDashboardValidationWarnings?: boolean;
|
||||
mysqlAnsiQuotes?: boolean;
|
||||
accessControlOnCall?: boolean;
|
||||
nestedFolders?: boolean;
|
||||
alertingBacktesting?: boolean;
|
||||
editPanelCSVDragAndDrop?: boolean;
|
||||
@@ -173,7 +171,6 @@ export interface FeatureToggles {
|
||||
newDashboardSharingComponent?: boolean;
|
||||
alertingListViewV2?: boolean;
|
||||
dashboardRestore?: boolean;
|
||||
datasourceProxyDisableRBAC?: boolean;
|
||||
alertingDisableSendAlertsExternal?: boolean;
|
||||
preserveDashboardStateWhenNavigating?: boolean;
|
||||
alertingCentralAlertHistory?: boolean;
|
||||
|
||||
@@ -4,6 +4,7 @@ export enum UnaryOperationID {
|
||||
Abs = 'abs',
|
||||
Exp = 'exp',
|
||||
Ln = 'ln',
|
||||
Round = 'round',
|
||||
Floor = 'floor',
|
||||
Ceil = 'ceil',
|
||||
}
|
||||
@@ -35,6 +36,12 @@ export const unaryOperators = new Registry<UnaryOperatorInfo>(() => {
|
||||
operation: (value: number) => Math.log(value),
|
||||
unaryOperationID: UnaryOperationID.Ln,
|
||||
},
|
||||
{
|
||||
id: UnaryOperationID.Round,
|
||||
name: 'Round',
|
||||
operation: (value: number) => Math.round(value),
|
||||
unaryOperationID: UnaryOperationID.Round,
|
||||
},
|
||||
{
|
||||
id: UnaryOperationID.Floor,
|
||||
name: 'Floor',
|
||||
|
||||
@@ -7,6 +7,7 @@ import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useTheme2 } from '../../themes';
|
||||
import { IconName } from '../../types/icon';
|
||||
import { t } from '../../utils/i18n';
|
||||
import { Button } from '../Button/Button';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { Box } from '../Layout/Box/Box';
|
||||
@@ -53,6 +54,8 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
|
||||
const role = restProps['role'] || rolesBySeverity[severity];
|
||||
const ariaLabel = restProps['aria-label'] || title;
|
||||
|
||||
const closeLabel = t('grafana-ui.alert.close-button', 'Close alert');
|
||||
|
||||
return (
|
||||
<div ref={ref} className={cx(styles.wrapper, className)} role={role} aria-label={ariaLabel} {...restProps}>
|
||||
<Box
|
||||
@@ -83,7 +86,7 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
|
||||
{onRemove && !buttonContent && (
|
||||
<div className={styles.close}>
|
||||
<Button
|
||||
aria-label="Close alert"
|
||||
aria-label={closeLabel}
|
||||
icon="times"
|
||||
onClick={onRemove}
|
||||
type="button"
|
||||
@@ -95,7 +98,7 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
|
||||
|
||||
{onRemove && buttonContent && (
|
||||
<Box marginLeft={1} display="flex" alignItems="center">
|
||||
<Button aria-label="Close alert" variant="secondary" onClick={onRemove} type="button">
|
||||
<Button aria-label={closeLabel} variant="secondary" onClick={onRemove} type="button">
|
||||
{buttonContent}
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { getFocusStyles } from '../../themes/mixins';
|
||||
import { t } from '../../utils/i18n';
|
||||
|
||||
import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer';
|
||||
|
||||
@@ -102,6 +103,7 @@ const Heading = ({ children, className, 'aria-label': ariaLabel }: ChildProps &
|
||||
onClick: undefined,
|
||||
isSelected: undefined,
|
||||
};
|
||||
const optionLabel = t('grafana-ui.card.option', 'option');
|
||||
|
||||
return (
|
||||
<h2 className={cx(styles.heading, className)}>
|
||||
@@ -117,7 +119,7 @@ const Heading = ({ children, className, 'aria-label': ariaLabel }: ChildProps &
|
||||
<>{children}</>
|
||||
)}
|
||||
{/* Input must be readonly because we are providing a value for the checked prop with no onChange handler */}
|
||||
{isSelected !== undefined && <input aria-label="option" type="radio" checked={isSelected} readOnly />}
|
||||
{isSelected !== undefined && <input aria-label={optionLabel} type="radio" checked={isSelected} readOnly />}
|
||||
</h2>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import { SelectableValue } from '@grafana/data';
|
||||
|
||||
import { withTheme2 } from '../../themes';
|
||||
import { Themeable2 } from '../../types';
|
||||
import { t } from '../../utils/i18n';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { IconButton } from '../IconButton/IconButton';
|
||||
import { Input } from '../Input/Input';
|
||||
@@ -286,7 +287,7 @@ class UnthemedCascader extends PureComponent<CascaderProps, CascaderState> {
|
||||
{isClearable && activeLabel !== '' && (
|
||||
<IconButton
|
||||
name="times"
|
||||
aria-label="Clear selection"
|
||||
aria-label={t('grafana-ui.cascader.clear-button', 'Clear selection')}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@@ -3,6 +3,7 @@ import { css } from '@emotion/css';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
|
||||
import { t } from '../../utils/i18n';
|
||||
|
||||
import { ColorSwatch } from './ColorSwatch';
|
||||
import NamedColorsGroup from './NamedColorsGroup';
|
||||
@@ -28,13 +29,13 @@ export const NamedColorsPalette = ({ color, onChange }: NamedColorsPaletteProps)
|
||||
<ColorSwatch
|
||||
isSelected={color === 'transparent'}
|
||||
color={'rgba(0,0,0,0)'}
|
||||
label="Transparent"
|
||||
label={t('grafana-ui.named-colors-palette.transparent-swatch', 'Transparent')}
|
||||
onClick={() => onChange('transparent')}
|
||||
/>
|
||||
<ColorSwatch
|
||||
isSelected={color === 'text'}
|
||||
color={theme.colors.text.primary}
|
||||
label="Text color"
|
||||
label={t('grafana-ui.named-colors-palette.text-color-swatch', 'Text color')}
|
||||
onClick={() => onChange('text')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { withTheme2 } from '../../themes';
|
||||
import { t } from '../../utils/i18n';
|
||||
import { InlineField } from '../Forms/InlineField';
|
||||
import { InlineSwitch } from '../Switch/Switch';
|
||||
import { PopoverContentProps } from '../Tooltip';
|
||||
@@ -12,15 +13,15 @@ export interface SeriesColorPickerPopoverProps extends ColorPickerProps, Popover
|
||||
|
||||
export const SeriesColorPickerPopover = (props: SeriesColorPickerPopoverProps) => {
|
||||
const { yaxis, onToggleAxis, color, ...colorPickerProps } = props;
|
||||
|
||||
const yAxisLabel = t('grafana-ui.series-color-picker-popover.y-axis-usage', 'Use right y-axis');
|
||||
const customPickers = onToggleAxis
|
||||
? {
|
||||
yaxis: {
|
||||
name: 'Y-Axis',
|
||||
tabComponent() {
|
||||
return (
|
||||
<InlineField labelWidth={20} label="Use right y-axis">
|
||||
<InlineSwitch value={yaxis === 2} label="Use right y-axis" onChange={onToggleAxis} />
|
||||
<InlineField labelWidth={20} label={yAxisLabel}>
|
||||
<InlineSwitch value={yaxis === 2} label={yAxisLabel} onChange={onToggleAxis} />
|
||||
</InlineField>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ import { forwardRef } from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { t } from '../../utils/i18n';
|
||||
import { IconButton } from '../IconButton/IconButton';
|
||||
|
||||
interface ValuePillProps {
|
||||
@@ -15,6 +16,7 @@ interface ValuePillProps {
|
||||
export const ValuePill = forwardRef<HTMLSpanElement, ValuePillProps>(
|
||||
({ children, onRemove, disabled, ...rest }, ref) => {
|
||||
const styles = useStyles2(getValuePillStyles, disabled);
|
||||
const removeButtonLabel = t('grafana-ui.value-pill.remove-button', 'Remove {{children}}', { children });
|
||||
return (
|
||||
<span className={styles.wrapper} {...rest} ref={ref}>
|
||||
<span className={styles.text}>{children}</span>
|
||||
@@ -24,7 +26,7 @@ export const ValuePill = forwardRef<HTMLSpanElement, ValuePillProps>(
|
||||
<IconButton
|
||||
name="times"
|
||||
size="md"
|
||||
aria-label={`Remove ${children}`}
|
||||
aria-label={removeButtonLabel}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onRemove();
|
||||
|
||||
@@ -7,6 +7,7 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { t } from '../../utils/i18n';
|
||||
import { Button, ButtonVariant } from '../Button';
|
||||
import { Field } from '../Forms/Field';
|
||||
import { Input } from '../Input/Input';
|
||||
@@ -90,7 +91,9 @@ export const ConfirmContent = ({
|
||||
};
|
||||
|
||||
const { handleSubmit } = useForm();
|
||||
|
||||
const placeholder = t('grafana-ui.confirm-content.placeholder', 'Type "{{confirmPromptText}}" to confirm', {
|
||||
confirmPromptText,
|
||||
});
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onConfirmClick)}>
|
||||
<div className={styles.text}>
|
||||
@@ -100,7 +103,7 @@ export const ConfirmContent = ({
|
||||
<div className={styles.confirmationInput}>
|
||||
<Stack alignItems="flex-start">
|
||||
<Field disabled={disabled}>
|
||||
<Input placeholder={`Type "${confirmPromptText}" to confirm`} onChange={onConfirmationTextChange} />
|
||||
<Input placeholder={placeholder} onChange={onConfirmationTextChange} />
|
||||
</Field>
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
@@ -53,15 +53,19 @@ export const DataLinkEditor = memo(
|
||||
|
||||
return (
|
||||
<div className={styles.listItem}>
|
||||
<Field label="Title">
|
||||
<Input value={value.title} onChange={onTitleChange} placeholder="Show details" />
|
||||
<Field label={t('grafana-ui.data-link-editor.title-label', 'Title')}>
|
||||
<Input
|
||||
value={value.title}
|
||||
onChange={onTitleChange}
|
||||
placeholder={t('grafana-ui.data-link-editor.title-placeholder', 'Show details')}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label="URL">
|
||||
<Field label={t('grafana-ui.data-link-editor.url-label', 'URL')}>
|
||||
<DataLinkInput value={value.url} onChange={onUrlChange} suggestions={suggestions} />
|
||||
</Field>
|
||||
|
||||
<Field label="Open in new tab">
|
||||
<Field label={t('grafana-ui.data-link-editor.new-tab-label', 'Open in new tab')}>
|
||||
<Switch value={value.targetBlank || false} onChange={onOpenInNewTabChanged} />
|
||||
</Field>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { DataLinksContextMenu } from './DataLinksContextMenu';
|
||||
|
||||
const fakeAriaLabel = 'fake aria label';
|
||||
describe('DataLinksContextMenu', () => {
|
||||
it('renders context menu when there are more than one data links or actions', () => {
|
||||
it('renders context menu when there are more than one data links', () => {
|
||||
render(
|
||||
<DataLinksContextMenu
|
||||
links={() => [
|
||||
@@ -23,7 +23,6 @@ describe('DataLinksContextMenu', () => {
|
||||
origin: {},
|
||||
},
|
||||
]}
|
||||
actions={[{ title: 'Action1', onClick: () => {} }]}
|
||||
>
|
||||
{() => {
|
||||
return <div aria-label="fake aria label" />;
|
||||
@@ -35,43 +34,7 @@ describe('DataLinksContextMenu', () => {
|
||||
expect(screen.queryAllByLabelText(selectors.components.DataLinksContextMenu.singleLink)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('renders context menu when there are actions and one data link', () => {
|
||||
render(
|
||||
<DataLinksContextMenu
|
||||
links={() => [
|
||||
{
|
||||
href: '/link1',
|
||||
title: 'Link1',
|
||||
target: '_blank',
|
||||
origin: {},
|
||||
},
|
||||
]}
|
||||
actions={[{ title: 'Action1', onClick: () => {} }]}
|
||||
>
|
||||
{() => {
|
||||
return <div aria-label="fake aria label" />;
|
||||
}}
|
||||
</DataLinksContextMenu>
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText(fakeAriaLabel)).toBeInTheDocument();
|
||||
expect(screen.queryAllByLabelText(selectors.components.DataLinksContextMenu.singleLink)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('renders context menu when there are only actions', () => {
|
||||
render(
|
||||
<DataLinksContextMenu links={() => []} actions={[{ title: 'Action1', onClick: () => {} }]}>
|
||||
{() => {
|
||||
return <div aria-label="fake aria label" />;
|
||||
}}
|
||||
</DataLinksContextMenu>
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText(fakeAriaLabel)).toBeInTheDocument();
|
||||
expect(screen.queryAllByLabelText(selectors.components.DataLinksContextMenu.singleLink)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('renders link when there is a single data link and no actions', () => {
|
||||
it('renders link when there is a single data link', () => {
|
||||
render(
|
||||
<DataLinksContextMenu
|
||||
links={() => [
|
||||
|
||||
@@ -2,11 +2,11 @@ import { css } from '@emotion/css';
|
||||
import { CSSProperties } from 'react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { ActionModel, GrafanaTheme2, LinkModel } from '@grafana/data';
|
||||
import { GrafanaTheme2, LinkModel } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { actionModelToContextMenuItems, linkModelToContextMenuItems } from '../../utils/dataLinks';
|
||||
import { linkModelToContextMenuItems } from '../../utils/dataLinks';
|
||||
import { WithContextMenu } from '../ContextMenu/WithContextMenu';
|
||||
import { MenuGroup, MenuItemsGroup } from '../Menu/MenuGroup';
|
||||
import { MenuItem } from '../Menu/MenuItem';
|
||||
@@ -15,7 +15,6 @@ export interface DataLinksContextMenuProps {
|
||||
children: (props: DataLinksContextMenuApi) => JSX.Element;
|
||||
links: () => LinkModel[];
|
||||
style?: CSSProperties;
|
||||
actions?: ActionModel[];
|
||||
}
|
||||
|
||||
export interface DataLinksContextMenuApi {
|
||||
@@ -23,16 +22,12 @@ export interface DataLinksContextMenuApi {
|
||||
targetClassName?: string;
|
||||
}
|
||||
|
||||
export const DataLinksContextMenu = ({ children, links, actions, style }: DataLinksContextMenuProps) => {
|
||||
export const DataLinksContextMenu = ({ children, links, style }: DataLinksContextMenuProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
const itemsGroup: MenuItemsGroup[] = [
|
||||
{ items: linkModelToContextMenuItems(links), label: Boolean(links().length) ? 'Data links' : '' },
|
||||
];
|
||||
const hasActions = Boolean(actions?.length);
|
||||
if (hasActions) {
|
||||
itemsGroup.push({ items: actionModelToContextMenuItems(actions!), label: 'Actions' });
|
||||
}
|
||||
|
||||
const linksCounter = itemsGroup[0].items.length;
|
||||
const renderMenuGroupItems = () => {
|
||||
@@ -59,7 +54,7 @@ export const DataLinksContextMenu = ({ children, links, actions, style }: DataLi
|
||||
cursor: 'context-menu',
|
||||
});
|
||||
|
||||
if (linksCounter > 1 || hasActions) {
|
||||
if (linksCounter > 1) {
|
||||
return (
|
||||
<WithContextMenu renderMenuItems={renderMenuGroupItems}>
|
||||
{({ openMenu }) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||
|
||||
import { InlineSwitch } from '../../components/Switch/Switch';
|
||||
import { Trans } from '../../utils/i18n';
|
||||
import { t, Trans } from '../../utils/i18n';
|
||||
import { InlineField } from '../Forms/InlineField';
|
||||
|
||||
export interface Props<T extends DataSourceJsonData>
|
||||
@@ -22,9 +22,12 @@ export function AlertingSettings<T extends AlertingConfig>({ options, onOptionsC
|
||||
<div className="gf-form">
|
||||
<InlineField
|
||||
labelWidth={29}
|
||||
label="Manage alert rules in Alerting UI"
|
||||
label={t('grafana-ui.data-source-settings.alerting-settings-label', 'Manage alert rules in Alerting UI')}
|
||||
disabled={options.readOnly}
|
||||
tooltip="Manage alert rules for this data source. To manage other alerting resources, add an Alertmanager data source."
|
||||
tooltip={t(
|
||||
'grafana-ui.data-source-settings.alerting-settings-tooltip',
|
||||
'Manage alert rules for this data source. To manage other alerting resources, add an Alertmanager data source.'
|
||||
)}
|
||||
>
|
||||
<InlineSwitch
|
||||
value={options.jsonData.manageAlerts !== false}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { InlineField } from '../../components/Forms/InlineField';
|
||||
import { t } from '../../utils/i18n';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
import { SecretFormField } from '../SecretFormField/SecretFormField';
|
||||
|
||||
@@ -37,10 +38,10 @@ export const BasicAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsPr
|
||||
<>
|
||||
<InlineField disabled={dataSourceConfig.readOnly}>
|
||||
<FormField
|
||||
label="User"
|
||||
label={t('grafana-ui.data-source-basic-auth-settings.user-label', 'User')}
|
||||
labelWidth={10}
|
||||
inputWidth={18}
|
||||
placeholder="user"
|
||||
placeholder={t('grafana-ui.data-source-basic-auth-settings.user-placeholder', 'user')}
|
||||
value={dataSourceConfig.basicAuthUser}
|
||||
onChange={(event) => onChange({ ...dataSourceConfig, basicAuthUser: event.currentTarget.value })}
|
||||
/>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { PureComponent } from 'react';
|
||||
import { DataSourceSettings } from '@grafana/data';
|
||||
|
||||
import { useStyles2 } from '../../themes';
|
||||
import { Trans } from '../../utils/i18n';
|
||||
import { t, Trans } from '../../utils/i18n';
|
||||
import { Button } from '../Button';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
@@ -59,8 +59,9 @@ const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }: Custom
|
||||
return (
|
||||
<div className={styles.layout}>
|
||||
<FormField
|
||||
label="Header"
|
||||
label={t('grafana-ui.data-source-settings.custom-headers-header', 'Header')}
|
||||
name="name"
|
||||
// eslint-disable-next-line @grafana/no-untranslated-strings
|
||||
placeholder="X-Custom-Header"
|
||||
labelWidth={5}
|
||||
value={header.name || ''}
|
||||
@@ -68,21 +69,21 @@ const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }: Custom
|
||||
onBlur={onBlur}
|
||||
/>
|
||||
<SecretFormField
|
||||
label="Value"
|
||||
aria-label="Value"
|
||||
label={t('grafana-ui.data-source-settings.custom-headers-header-value', 'Value')}
|
||||
aria-label={t('grafana-ui.data-source-settings.custom-headers-header-value', 'Value')}
|
||||
name="value"
|
||||
isConfigured={header.configured}
|
||||
value={header.value}
|
||||
labelWidth={5}
|
||||
inputWidth={header.configured ? 11 : 12}
|
||||
placeholder="Header Value"
|
||||
placeholder={t('grafana-ui.data-source-settings.custom-headers-header-placeholder', 'Header Value')}
|
||||
onReset={() => onReset(header.id)}
|
||||
onChange={(e) => onChange({ ...header, value: e.target.value })}
|
||||
onBlur={onBlur}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
aria-label="Remove header"
|
||||
aria-label={t('grafana-ui.data-source-settings.custom-headers-header-remove', 'Remove header')}
|
||||
variant="secondary"
|
||||
size="xs"
|
||||
onClick={(_e) => onRemove(header.id)}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SelectableValue } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useTheme2 } from '../../themes';
|
||||
import { Trans } from '../../utils/i18n';
|
||||
import { t, Trans } from '../../utils/i18n';
|
||||
import { Alert } from '../Alert/Alert';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
import { InlineFormLabel } from '../FormLabel/FormLabel';
|
||||
@@ -26,22 +26,23 @@ import { HttpSettingsProps } from './types';
|
||||
|
||||
const ACCESS_OPTIONS: Array<SelectableValue<string>> = [
|
||||
{
|
||||
label: 'Server (default)',
|
||||
label: t('grafana-ui.data-source-http-settings.access-options-proxy', 'Server (default)'),
|
||||
value: 'proxy',
|
||||
},
|
||||
{
|
||||
label: 'Browser',
|
||||
label: t('grafana-ui.data-source-http-settings.access-options-browser', 'Browser'),
|
||||
value: 'direct',
|
||||
},
|
||||
];
|
||||
|
||||
const DEFAULT_ACCESS_OPTION = {
|
||||
label: 'Server (default)',
|
||||
label: t('grafana-ui.data-source-http-settings.access-options-proxy', 'Server (default)'),
|
||||
value: 'proxy',
|
||||
};
|
||||
|
||||
const HttpAccessHelp = () => {
|
||||
return (
|
||||
// eslint-disable-next-line @grafana/no-untranslated-strings
|
||||
<Alert severity="info" title="" topSpacing={3}>
|
||||
<p>
|
||||
<Trans i18nKey="grafana-ui.data-source-http-settings.access-help-details">
|
||||
@@ -161,7 +162,7 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
|
||||
const accessSelect = (
|
||||
<Select
|
||||
aria-label="Access"
|
||||
aria-label={t('grafana-ui.data-source-http-settings.default-url-access-select', 'Access')}
|
||||
className="width-20 gf-form-input"
|
||||
options={ACCESS_OPTIONS}
|
||||
value={ACCESS_OPTIONS.filter((o) => o.value === dataSourceConfig.access)[0] || DEFAULT_ACCESS_OPTION}
|
||||
@@ -204,7 +205,7 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
interactive={urlDocs ? true : false}
|
||||
label={urlLabel ?? 'URL'}
|
||||
label={urlLabel ?? t('grafana-ui.data-source-http-settings.url-label', 'URL')}
|
||||
labelWidth={13}
|
||||
tooltip={urlTooltip}
|
||||
inputEl={urlInput}
|
||||
@@ -215,7 +216,12 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<FormField label="Access" labelWidth={13} inputWidth={20} inputEl={accessSelect} />
|
||||
<FormField
|
||||
label={t('grafana-ui.data-source-http-settings.access-label', 'Access')}
|
||||
labelWidth={13}
|
||||
inputWidth={20}
|
||||
inputEl={accessSelect}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<button
|
||||
@@ -238,7 +244,10 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
<div className="gf-form">
|
||||
<InlineFormLabel
|
||||
width={13}
|
||||
tooltip="Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source."
|
||||
tooltip={t(
|
||||
'grafana-ui.data-source-http-settings.allowed-cookies-tooltip',
|
||||
'Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.'
|
||||
)}
|
||||
>
|
||||
<Trans i18nKey="grafana-ui.data-source-http-settings.allowed-cookies">Allowed cookies</Trans>
|
||||
</InlineFormLabel>
|
||||
@@ -253,13 +262,13 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
label="Timeout"
|
||||
label={t('grafana-ui.data-source-http-settings.timeout-form-label', 'Timeout')}
|
||||
type="number"
|
||||
labelWidth={13}
|
||||
inputWidth={20}
|
||||
tooltip="HTTP request timeout in seconds"
|
||||
placeholder="Timeout in seconds"
|
||||
aria-label="Timeout in seconds"
|
||||
tooltip={t('grafana-ui.data-source-http-settings.timeout-tooltip', 'HTTP request timeout in seconds')}
|
||||
placeholder={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout in seconds')}
|
||||
aria-label={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout in seconds')}
|
||||
value={dataSourceConfig.jsonData.timeout}
|
||||
onChange={(event) => {
|
||||
onSettingsChange({
|
||||
@@ -280,7 +289,11 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
</h3>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form-inline">
|
||||
<InlineField label="Basic auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||
<InlineField
|
||||
label={t('grafana-ui.data-source-http-settings.basic-auth-label', 'Basic auth')}
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
<InlineSwitch
|
||||
id="http-settings-basic-auth"
|
||||
value={dataSourceConfig.basicAuth}
|
||||
@@ -291,8 +304,11 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
</InlineField>
|
||||
|
||||
<InlineField
|
||||
label="With Credentials"
|
||||
tooltip="Whether credentials such as cookies or auth headers should be sent with cross-site requests."
|
||||
label={t('grafana-ui.data-source-http-settings.with-credential-label', 'With Credentials')}
|
||||
tooltip={t(
|
||||
'grafana-ui.data-source-http-settings.with-credential-tooltip',
|
||||
'Whether credentials such as cookies or auth headers should be sent with cross-site requests.'
|
||||
)}
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
@@ -309,8 +325,11 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
{azureAuthSettings?.azureAuthSupported && (
|
||||
<div className="gf-form-inline">
|
||||
<InlineField
|
||||
label="Azure Authentication"
|
||||
tooltip="Use Azure authentication for Azure endpoint."
|
||||
label={t('grafana-ui.data-source-http-settings.azure-auth-label', 'Azure Authentication')}
|
||||
tooltip={t(
|
||||
'grafana-ui.data-source-http-settings.azure-auth-tooltip',
|
||||
'Use Azure authentication for Azure endpoint.'
|
||||
)}
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
@@ -329,7 +348,12 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
|
||||
|
||||
{sigV4AuthToggleEnabled && (
|
||||
<div className="gf-form-inline">
|
||||
<InlineField label="SigV4 auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||
<InlineField
|
||||
// eslint-disable-next-line @grafana/no-untranslated-strings
|
||||
label="SigV4 auth"
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
<InlineSwitch
|
||||
id="http-settings-sigv4-auth"
|
||||
value={dataSourceConfig.jsonData.sigV4Auth || false}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { t } from '../../utils/i18n';
|
||||
import { InlineField } from '../Forms/InlineField';
|
||||
import { InlineSwitch } from '../Switch/Switch';
|
||||
|
||||
@@ -13,7 +14,11 @@ export const HttpProxySettings = ({
|
||||
return (
|
||||
<>
|
||||
<div className="gf-form-inline">
|
||||
<InlineField label="TLS Client Auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||
<InlineField
|
||||
label={t('grafana-ui.data-source-http-proxy-settings.ts-client-auth-label', 'TLS Client Auth')}
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
<InlineSwitch
|
||||
id="http-settings-tls-client-auth"
|
||||
value={dataSourceConfig.jsonData.tlsAuth || false}
|
||||
@@ -21,8 +26,11 @@ export const HttpProxySettings = ({
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="With CA Cert"
|
||||
tooltip="Needed for verifying self-signed TLS Certs"
|
||||
label={t('grafana-ui.data-source-http-proxy-settings.with-ca-cert-label', 'With CA Cert')}
|
||||
tooltip={t(
|
||||
'grafana-ui.data-source-http-proxy-settings.with-ca-cert-tooltip',
|
||||
'Needed for verifying self-signed TLS Certs'
|
||||
)}
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
@@ -36,7 +44,11 @@ export const HttpProxySettings = ({
|
||||
</InlineField>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
<InlineField label="Skip TLS Verify" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
|
||||
<InlineField
|
||||
label={t('grafana-ui.data-source-http-proxy-settings.skip-tls-verify-label', 'Skip TLS Verify')}
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
<InlineSwitch
|
||||
id="http-settings-skip-tls-verify"
|
||||
value={dataSourceConfig.jsonData.tlsSkipVerify || false}
|
||||
@@ -49,8 +61,11 @@ export const HttpProxySettings = ({
|
||||
{showForwardOAuthIdentityOption && (
|
||||
<div className="gf-form-inline">
|
||||
<InlineField
|
||||
label="Forward OAuth Identity"
|
||||
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
|
||||
label={t('grafana-ui.data-source-http-proxy-settings.oauth-identity-label', 'Forward OAuth Identity')}
|
||||
tooltip={t(
|
||||
'grafana-ui.data-source-http-proxy-settings.oauth-identity-tooltip',
|
||||
"Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
|
||||
)}
|
||||
labelWidth={LABEL_WIDTH}
|
||||
disabled={dataSourceConfig.readOnly}
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||
|
||||
import { InlineSwitch } from '../../components/Switch/Switch';
|
||||
import { Trans } from '../../utils/i18n';
|
||||
import { t, Trans } from '../../utils/i18n';
|
||||
import { InlineField } from '../Forms/InlineField';
|
||||
|
||||
export interface Props<T extends DataSourceJsonData>
|
||||
@@ -25,8 +25,11 @@ export function SecureSocksProxySettings<T extends SecureSocksProxyConfig>({
|
||||
<div className="gf-form">
|
||||
<InlineField
|
||||
labelWidth={26}
|
||||
label="Enabled"
|
||||
tooltip="Connect to this datasource via the secure socks proxy."
|
||||
label={t('grafana-ui.data-source-settings.secure-socks-label', 'Enabled')}
|
||||
tooltip={t(
|
||||
'grafana-ui.data-source-settings.secure-socks-tooltip',
|
||||
'Connect to this datasource via the secure socks proxy.'
|
||||
)}
|
||||
>
|
||||
<InlineSwitch
|
||||
value={options.jsonData.enableSecureSocksProxy ?? false}
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as React from 'react';
|
||||
|
||||
import { KeyValue } from '@grafana/data';
|
||||
|
||||
import { Trans } from '../../utils/i18n';
|
||||
import { t, Trans } from '../../utils/i18n';
|
||||
import { FormField } from '../FormField/FormField';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import { Tooltip } from '../Tooltip/Tooltip';
|
||||
@@ -49,6 +49,9 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
|
||||
});
|
||||
};
|
||||
|
||||
const certificateBeginsWith = '-----BEGIN CERTIFICATE-----';
|
||||
const privateKeyBeginsWith = '-----BEGIN RSA PRIVATE KEY-----';
|
||||
|
||||
return (
|
||||
<div className="gf-form-group">
|
||||
<div
|
||||
@@ -64,7 +67,10 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
|
||||
</h6>
|
||||
<Tooltip
|
||||
placement="right-end"
|
||||
content="TLS/SSL Certs are encrypted and stored in the Grafana database."
|
||||
content={t(
|
||||
'grafana-ui.data-source-settings.tls-tooltip',
|
||||
'TLS/SSL Certs are encrypted and stored in the Grafana database.'
|
||||
)}
|
||||
theme="info"
|
||||
>
|
||||
<Icon name="info-circle" size="xs" style={{ marginLeft: '10px' }} />
|
||||
@@ -75,8 +81,12 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
|
||||
<CertificationKey
|
||||
hasCert={!!hasTLSCACert}
|
||||
onChange={onCertificateChangeFactory('tlsCACert')}
|
||||
placeholder="Begins with -----BEGIN CERTIFICATE-----"
|
||||
label="CA Cert"
|
||||
placeholder={t(
|
||||
'grafana-ui.data-source-settings.tls-certification-placeholder',
|
||||
'Begins with {{certificateBeginsWith}}',
|
||||
{ certificateBeginsWith }
|
||||
)}
|
||||
label={t('grafana-ui.data-source-settings.tls-certification-label', 'CA Cert')}
|
||||
onClick={onResetClickFactory('tlsCACert')}
|
||||
/>
|
||||
)}
|
||||
@@ -85,9 +95,10 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
|
||||
<>
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
label="ServerName"
|
||||
label={t('grafana-ui.data-source-settings.tls-server-name-label', 'ServerName')}
|
||||
labelWidth={7}
|
||||
inputWidth={30}
|
||||
// eslint-disable-next-line @grafana/no-untranslated-strings
|
||||
placeholder="domain.example.com"
|
||||
value={hasServerName && dataSourceConfig.jsonData.serverName}
|
||||
onChange={onServerNameLabelChange}
|
||||
@@ -95,16 +106,24 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
|
||||
</div>
|
||||
<CertificationKey
|
||||
hasCert={!!hasTLSClientCert}
|
||||
label="Client Cert"
|
||||
label={t('grafana-ui.data-source-settings.tls-client-certification-label', 'Client Cert')}
|
||||
onChange={onCertificateChangeFactory('tlsClientCert')}
|
||||
placeholder="Begins with -----BEGIN CERTIFICATE-----"
|
||||
placeholder={t(
|
||||
'grafana-ui.data-source-settings.tls-certification-placeholder',
|
||||
'Begins with {{certificateBeginsWith}}',
|
||||
{ certificateBeginsWith }
|
||||
)}
|
||||
onClick={onResetClickFactory('tlsClientCert')}
|
||||
/>
|
||||
|
||||
<CertificationKey
|
||||
hasCert={!!hasTLSClientKey}
|
||||
label="Client Key"
|
||||
placeholder="Begins with -----BEGIN RSA PRIVATE KEY-----"
|
||||
label={t('grafana-ui.data-source-settings.tls-client-key-label', 'Client Key')}
|
||||
placeholder={t(
|
||||
'grafana-ui.data-source-settings.tls-client-key-placeholder',
|
||||
'Begins with {{privateKeyBeginsWith}}',
|
||||
{ privateKeyBeginsWith }
|
||||
)}
|
||||
onChange={onCertificateChangeFactory('tlsClientKey')}
|
||||
onClick={onResetClickFactory('tlsClientKey')}
|
||||
/>
|
||||
|
||||
+12
-5
@@ -21,7 +21,7 @@ import {
|
||||
import { Components } from '@grafana/e2e-selectors';
|
||||
|
||||
import { useStyles2, useTheme2 } from '../../../themes';
|
||||
import { Trans } from '../../../utils/i18n';
|
||||
import { t, Trans } from '../../../utils/i18n';
|
||||
import { Button } from '../../Button/Button';
|
||||
import { InlineField } from '../../Forms/InlineField';
|
||||
import { Icon } from '../../Icon/Icon';
|
||||
@@ -253,7 +253,14 @@ const DateTimeInput = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
onChange();
|
||||
}, [onChange]);
|
||||
|
||||
const icon = <Button aria-label="Time picker" icon="calendar-alt" variant="secondary" onClick={onOpen} />;
|
||||
const icon = (
|
||||
<Button
|
||||
aria-label={t('grafana-ui.date-time-picker.calendar-icon-label', 'Time picker')}
|
||||
icon="calendar-alt"
|
||||
variant="secondary"
|
||||
onClick={onOpen}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<InlineField label={label} invalid={!!(internalDate.value && internalDate.invalid)} className={styles.field}>
|
||||
<Input
|
||||
@@ -262,7 +269,7 @@ const DateTimeInput = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
value={internalDate.value}
|
||||
onBlur={onBlur}
|
||||
data-testid={Components.DateTimePicker.input}
|
||||
placeholder="Select date/time"
|
||||
placeholder={t('grafana-ui.date-time-picker.select-placeholder', 'Select date/time')}
|
||||
ref={ref}
|
||||
suffix={
|
||||
clearable &&
|
||||
@@ -343,9 +350,9 @@ const DateTimeCalendar = React.forwardRef<HTMLDivElement, DateTimeCalendarProps>
|
||||
prev2Label={null}
|
||||
value={reactCalendarDate}
|
||||
nextLabel={<Icon name="angle-right" />}
|
||||
nextAriaLabel="Next month"
|
||||
nextAriaLabel={t('grafana-ui.date-time-picker.next-label', 'Next month')}
|
||||
prevLabel={<Icon name="angle-left" />}
|
||||
prevAriaLabel="Previous month"
|
||||
prevAriaLabel={t('grafana-ui.date-time-picker.previous-label', 'Previous month')}
|
||||
onChange={onChangeDate}
|
||||
locale="en"
|
||||
className={calendarStyles.body}
|
||||
|
||||
+14
-3
@@ -179,7 +179,11 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
|
||||
</Tooltip>
|
||||
</TimePickerTitle>
|
||||
</div>
|
||||
<Field label="From" invalid={!from.validation.isValid} error={from.validation.errorMessage}>
|
||||
<Field
|
||||
label={t('time-picker.time-range.from-label', 'From')}
|
||||
invalid={!from.validation.isValid}
|
||||
error={from.validation.errorMessage}
|
||||
>
|
||||
<Input
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
onBlur={() => setFrom({ ...from, validation: isRangeValid(from.value) })}
|
||||
@@ -187,7 +191,11 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
|
||||
value={from.value}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="To" invalid={!to.validation.isValid} error={to.validation.errorMessage}>
|
||||
<Field
|
||||
label={t('time-picker.time-range.to-label', 'To')}
|
||||
invalid={!to.validation.isValid}
|
||||
error={to.validation.errorMessage}
|
||||
>
|
||||
<Input
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
onBlur={() => setTo({ ...to, validation: isRangeValid(to.value) })}
|
||||
@@ -195,7 +203,10 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
|
||||
value={to.value}
|
||||
/>
|
||||
</Field>
|
||||
<Button aria-label="TimePicker submit button" onClick={onApply}>
|
||||
<Button
|
||||
aria-label={t('time-picker.time-range.submit-button-label', 'TimePicker submit button')}
|
||||
onClick={onApply}
|
||||
>
|
||||
<Trans i18nKey="time-picker.time-range.apply">Apply time range</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@ const defaultScale: ThresholdsConfig = {
|
||||
};
|
||||
|
||||
export const BarGaugeCell = (props: TableCellProps) => {
|
||||
const { field, innerWidth, tableStyles, cell, cellProps, row, actions } = props;
|
||||
const { field, innerWidth, tableStyles, cell, cellProps, row } = props;
|
||||
const displayValue = field.display!(cell.value);
|
||||
const cellOptions = getCellOptions(field);
|
||||
|
||||
@@ -56,7 +56,6 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
||||
};
|
||||
|
||||
const hasLinks = Boolean(getLinks().length);
|
||||
const hasActions = Boolean(actions?.length);
|
||||
const alignmentFactors = getAlignmentFactor(field, displayValue, cell.row.index);
|
||||
|
||||
const renderComponent = (menuProps: DataLinksContextMenuApi) => {
|
||||
@@ -85,8 +84,8 @@ export const BarGaugeCell = (props: TableCellProps) => {
|
||||
|
||||
return (
|
||||
<div {...cellProps} className={tableStyles.cellContainer}>
|
||||
{hasLinks || hasActions ? (
|
||||
<DataLinksContextMenu links={getLinks} actions={actions} style={{ display: 'flex', width: '100%' }}>
|
||||
{hasLinks ? (
|
||||
<DataLinksContextMenu links={getLinks} style={{ display: 'flex', width: '100%' }}>
|
||||
{(api) => renderComponent(api)}
|
||||
</DataLinksContextMenu>
|
||||
) : (
|
||||
|
||||
@@ -17,8 +17,7 @@ import { TableCellProps, CustomCellRendererProps, TableCellOptions } from './typ
|
||||
import { getCellColors, getCellOptions } from './utils';
|
||||
|
||||
export const DefaultCell = (props: TableCellProps) => {
|
||||
const { field, cell, tableStyles, row, cellProps, frame, rowStyled, rowExpanded, textWrapped, height, actions } =
|
||||
props;
|
||||
const { field, cell, tableStyles, row, cellProps, frame, rowStyled, rowExpanded, textWrapped, height } = props;
|
||||
const inspectEnabled = Boolean(field.config.custom?.inspect);
|
||||
const displayValue = field.display!(cell.value);
|
||||
|
||||
@@ -26,7 +25,6 @@ export const DefaultCell = (props: TableCellProps) => {
|
||||
const showActions = (showFilters && cell.value !== undefined) || inspectEnabled;
|
||||
const cellOptions = getCellOptions(field);
|
||||
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
||||
const hasActions = Boolean(actions?.length);
|
||||
const clearButtonStyle = useStyles2(clearLinkButtonStyles);
|
||||
let value: string | ReactElement;
|
||||
|
||||
@@ -81,8 +79,8 @@ export const DefaultCell = (props: TableCellProps) => {
|
||||
|
||||
return (
|
||||
<div key={key} {...rest} className={cellStyle}>
|
||||
{hasLinks || hasActions ? (
|
||||
<DataLinksContextMenu links={() => getCellLinks(field, row) || []} actions={actions}>
|
||||
{hasLinks ? (
|
||||
<DataLinksContextMenu links={() => getCellLinks(field, row) || []}>
|
||||
{(api) => {
|
||||
if (api.openMenu) {
|
||||
return (
|
||||
|
||||
@@ -9,13 +9,12 @@ import { getCellOptions } from './utils';
|
||||
const DATALINKS_HEIGHT_OFFSET = 10;
|
||||
|
||||
export const ImageCell = (props: TableCellProps) => {
|
||||
const { field, cell, tableStyles, row, cellProps, actions } = props;
|
||||
const { field, cell, tableStyles, row, cellProps } = props;
|
||||
const cellOptions = getCellOptions(field);
|
||||
const { title, alt } =
|
||||
cellOptions.type === TableCellDisplayMode.Image ? cellOptions : { title: undefined, alt: undefined };
|
||||
const displayValue = field.display!(cell.value);
|
||||
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
||||
const hasActions = Boolean(actions?.length);
|
||||
|
||||
// The image element
|
||||
const img = (
|
||||
@@ -32,11 +31,10 @@ export const ImageCell = (props: TableCellProps) => {
|
||||
<div {...cellProps} className={tableStyles.cellContainer}>
|
||||
{/* If there are data links/actions, we render them with image */}
|
||||
{/* Otherwise we simply render the image */}
|
||||
{hasLinks || hasActions ? (
|
||||
{hasLinks ? (
|
||||
<DataLinksContextMenu
|
||||
style={{ height: tableStyles.cellHeight - DATALINKS_HEIGHT_OFFSET, width: 'auto' }}
|
||||
links={() => getCellLinks(field, row) || []}
|
||||
actions={actions}
|
||||
>
|
||||
{(api) => {
|
||||
if (api.openMenu) {
|
||||
|
||||
@@ -11,7 +11,7 @@ import { TableCellInspectorMode } from './TableCellInspector';
|
||||
import { TableCellProps } from './types';
|
||||
|
||||
export function JSONViewCell(props: TableCellProps): JSX.Element {
|
||||
const { cell, tableStyles, cellProps, field, row, actions } = props;
|
||||
const { cell, tableStyles, cellProps, field, row } = props;
|
||||
const inspectEnabled = Boolean(field.config.custom?.inspect);
|
||||
const txt = css({
|
||||
cursor: 'pointer',
|
||||
@@ -30,14 +30,13 @@ export function JSONViewCell(props: TableCellProps): JSX.Element {
|
||||
}
|
||||
|
||||
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
||||
const hasActions = Boolean(actions?.length);
|
||||
const clearButtonStyle = useStyles2(clearLinkButtonStyles);
|
||||
|
||||
return (
|
||||
<div {...cellProps} className={inspectEnabled ? tableStyles.cellContainerNoOverflow : tableStyles.cellContainer}>
|
||||
<div className={cx(tableStyles.cellText, txt)}>
|
||||
{hasLinks || hasActions ? (
|
||||
<DataLinksContextMenu links={() => getCellLinks(field, row) || []} actions={actions}>
|
||||
{hasLinks ? (
|
||||
<DataLinksContextMenu links={() => getCellLinks(field, row) || []}>
|
||||
{(api) => {
|
||||
if (api.openMenu) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ActionModel, LinkModel } from '@grafana/data';
|
||||
import { LinkModel } from '@grafana/data';
|
||||
|
||||
import { MenuItemProps } from '../components/Menu/MenuItem';
|
||||
|
||||
@@ -18,14 +18,3 @@ export const linkModelToContextMenuItems: (links: () => LinkModel[]) => MenuItem
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const actionModelToContextMenuItems: (actions: ActionModel[]) => MenuItemProps[] = (actions) => {
|
||||
return actions.map((action) => {
|
||||
return {
|
||||
label: action.title,
|
||||
ariaLabel: action.title,
|
||||
icon: 'record-audio',
|
||||
onClick: action.onClick,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ toolchain go1.23.6
|
||||
|
||||
require (
|
||||
github.com/emicklei/go-restful/v3 v3.11.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.266.0
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.267.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
|
||||
@@ -39,7 +39,7 @@ require (
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/elazarl/goproxy v1.7.0 // indirect
|
||||
github.com/elazarl/goproxy v1.7.1 // 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
|
||||
@@ -59,7 +59,7 @@ require (
|
||||
github.com/google/cel-go v0.22.1 // indirect
|
||||
github.com/google/flatbuffers v24.3.25+incompatible // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
@@ -150,7 +150,7 @@ require (
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
|
||||
@@ -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.0 h1:EXv2nV4EjM60ZtsEVLYJG4oBXhDGutMKperpHsZ/v+0=
|
||||
github.com/elazarl/goproxy v1.7.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ=
|
||||
github.com/elazarl/goproxy v1.7.1 h1:1P7LPSxbqtNxusFnXclj6O56pjfq1xOQZ6a0mwwKUlY=
|
||||
github.com/elazarl/goproxy v1.7.1/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=
|
||||
@@ -118,8 +118,9 @@ github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvR
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -134,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.266.0 h1:YP+iEpXH3HRX9Xo4NHjsrJhN2W7uVTtkLNzMHYbmiLI=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.266.0/go.mod h1:bxkXrBQ4QSmOncsWdIOcpgP+M6wajQNMAPXlbWrqAWY=
|
||||
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/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=
|
||||
@@ -495,8 +496,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
@@ -66,18 +66,11 @@ func (hs *HTTPServer) declareFixedRoles() error {
|
||||
{
|
||||
Action: ac.ActionDatasourcesExplore,
|
||||
},
|
||||
{
|
||||
Action: ac.ActionDatasourcesDrilldown,
|
||||
},
|
||||
},
|
||||
},
|
||||
Grants: []string{string(org.RoleEditor)},
|
||||
}
|
||||
|
||||
if hs.Cfg.ViewersCanEdit {
|
||||
datasourcesExplorerRole.Grants = append(datasourcesExplorerRole.Grants, string(org.RoleViewer))
|
||||
}
|
||||
|
||||
datasourcesReaderRole := ac.RoleRegistration{
|
||||
Role: ac.RoleDTO{
|
||||
Name: "fixed:datasources:reader",
|
||||
|
||||
+2
-2
@@ -66,7 +66,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
reqSignedInNoAnonymous := middleware.ReqSignedInNoAnonymous
|
||||
reqGrafanaAdmin := middleware.ReqGrafanaAdmin
|
||||
reqOrgAdmin := middleware.ReqOrgAdmin
|
||||
reqRoleForAppRoute := middleware.RoleAppPluginAuth(hs.AccessControl, hs.pluginStore, hs.Features, hs.log)
|
||||
reqRoleForAppRoute := middleware.RoleAppPluginAuth(hs.AccessControl, hs.pluginStore, hs.log)
|
||||
reqSnapshotPublicModeOrCreate := middleware.SnapshotPublicModeOrCreate(hs.Cfg, hs.AccessControl)
|
||||
reqSnapshotPublicModeOrDelete := middleware.SnapshotPublicModeOrDelete(hs.Cfg, hs.AccessControl)
|
||||
redirectFromLegacyPanelEditURL := middleware.RedirectFromLegacyPanelEditURL(hs.Cfg)
|
||||
@@ -183,7 +183,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
}
|
||||
|
||||
r.Get("/explore", authorize(ac.EvalPermission(ac.ActionDatasourcesExplore)), hs.Index)
|
||||
r.Get("/drilldown", authorize(ac.EvalPermission(ac.ActionDatasourcesDrilldown)), hs.Index)
|
||||
r.Get("/drilldown", authorize(ac.EvalPermission(ac.ActionDatasourcesExplore)), hs.Index)
|
||||
|
||||
r.Get("/playlists/", reqSignedIn, hs.Index)
|
||||
r.Get("/playlists/*", reqSignedIn, hs.Index)
|
||||
|
||||
@@ -306,16 +306,8 @@ func (proxy *DataSourceProxy) validateRequest() error {
|
||||
continue
|
||||
}
|
||||
|
||||
if proxy.features.IsEnabled(proxy.ctx.Req.Context(), featuremgmt.FlagDatasourceProxyDisableRBAC) {
|
||||
// TODO(aarongodin): following logic can be removed with FlagDatasourceProxyDisableRBAC as it is covered by
|
||||
// proxy.hasAccessToRoute(..)
|
||||
if route.ReqRole.IsValid() && !proxy.ctx.HasUserRole(route.ReqRole) {
|
||||
return errors.New("plugin proxy route access denied")
|
||||
}
|
||||
} else {
|
||||
if !proxy.hasAccessToRoute(route) {
|
||||
return errors.New("plugin proxy route access denied")
|
||||
}
|
||||
if !proxy.hasAccessToRoute(route) {
|
||||
return errors.New("plugin proxy route access denied")
|
||||
}
|
||||
|
||||
proxy.matchedRoute = route
|
||||
@@ -340,8 +332,7 @@ func (proxy *DataSourceProxy) validateRequest() error {
|
||||
|
||||
func (proxy *DataSourceProxy) hasAccessToRoute(route *plugins.Route) bool {
|
||||
ctxLogger := logger.FromContext(proxy.ctx.Req.Context())
|
||||
useRBAC := proxy.features.IsEnabled(proxy.ctx.Req.Context(), featuremgmt.FlagAccessControlOnCall) && route.ReqAction != ""
|
||||
if useRBAC {
|
||||
if route.ReqAction != "" {
|
||||
routeEval := pluginac.GetDataSourceRouteEvaluator(proxy.ds.UID, route.ReqAction)
|
||||
hasAccess := routeEval.Evaluate(proxy.ctx.GetPermissions())
|
||||
if !hasAccess {
|
||||
|
||||
@@ -1094,7 +1094,7 @@ func setupDSProxyTest(t *testing.T, ctx *contextmodel.ReqContext, ds *datasource
|
||||
cfg := setting.NewCfg()
|
||||
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||
secretsStore := secretskvs.NewSQLSecretsKVStore(dbtest.NewFakeDB(), secretsService, log.NewNopLogger())
|
||||
features := featuremgmt.WithFeatures(featuremgmt.FlagAccessControlOnCall)
|
||||
features := featuremgmt.WithFeatures()
|
||||
dsService, err := datasourceservice.ProvideService(nil, secretsService, secretsStore, cfg, features, acimpl.ProvideAccessControl(features),
|
||||
&actest.FakePermissionsService{}, quotatest.New(false, nil), &pluginstore.FakePluginStore{}, &pluginfakes.FakePluginClient{},
|
||||
plugincontext.ProvideBaseService(cfg, pluginconfig.NewFakePluginRequestConfigProvider()))
|
||||
|
||||
@@ -129,8 +129,7 @@ func (proxy *PluginProxy) HandleRequest() {
|
||||
}
|
||||
|
||||
func (proxy *PluginProxy) hasAccessToRoute(route *plugins.Route) bool {
|
||||
useRBAC := proxy.features.IsEnabled(proxy.ctx.Req.Context(), featuremgmt.FlagAccessControlOnCall) && route.ReqAction != ""
|
||||
if useRBAC {
|
||||
if route.ReqAction != "" {
|
||||
routeEval := pluginac.GetPluginRouteEvaluator(proxy.ps.PluginID, route.ReqAction)
|
||||
hasAccess := ac.HasAccess(proxy.accessControl, proxy.ctx)(routeEval)
|
||||
if !hasAccess {
|
||||
|
||||
@@ -557,7 +557,7 @@ func TestPluginProxyRoutesAccessControl(t *testing.T) {
|
||||
SecureJSONData: map[string][]byte{},
|
||||
}
|
||||
cfg := &setting.Cfg{}
|
||||
proxy, err := NewPluginProxy(ps, testRoutes, ctx, tc.proxyPath, cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), featuremgmt.WithFeatures(featuremgmt.FlagAccessControlOnCall))
|
||||
proxy, err := NewPluginProxy(ps, testRoutes, ctx, tc.proxyPath, cfg, secretsService, tracing.InitializeTracerForTest(), &http.Transport{}, acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), featuremgmt.WithFeatures())
|
||||
require.NoError(t, err)
|
||||
proxy.HandleRequest()
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ module github.com/grafana/grafana/pkg/apimachinery
|
||||
go 1.23.1
|
||||
|
||||
require (
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 // @grafana/identity-access-team
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 // @grafana/identity-access-team
|
||||
github.com/grafana/authlib v0.0.0-20250225105729-99e678595501 // @grafana/identity-access-team
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 // @grafana/identity-access-team
|
||||
github.com/stretchr/testify v1.10.0
|
||||
k8s.io/apimachinery v0.32.1
|
||||
k8s.io/apiserver v0.32.1
|
||||
@@ -23,6 +23,7 @@ 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
|
||||
@@ -43,7 +44,7 @@ require (
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
|
||||
@@ -25,17 +25,17 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7 h1:NTMmow+74I3Jb033xhbRgWQS7A//5TDhiM4tl7bsVP4=
|
||||
github.com/grafana/authlib v0.0.0-20250219100139-6a3b1bbb50e7/go.mod h1:T3X4z0ejGfJOiOmZLFeKCRT/yxWJq/RtclAc/PHj/w4=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 h1:EokLC5grHwLPs4tXW8T6E8187H1e5G9AP0QQ5B60HbA=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/authlib v0.0.0-20250225105729-99e678595501 h1:FTuDRy/Shw8yOdG+v1DnkeuaCAl8fvwgcfaG9Wccuhg=
|
||||
github.com/grafana/authlib v0.0.0-20250225105729-99e678595501/go.mod h1:XVpdLhaeYqz414FmGnW00/0vTe1x8c0GRH3KaeRtyg0=
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 h1:DnRUYiAotHXnrfYJCvhH1NkiyWVcPm5Pd+P7Ugqt/d8=
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@@ -151,8 +151,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
@@ -5,8 +5,8 @@ go 1.23.4
|
||||
toolchain go1.23.6
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
@@ -93,7 +93,7 @@ require (
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
@@ -68,8 +68,8 @@ github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvR
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -79,8 +79,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31 h1:EokLC5grHwLPs4tXW8T6E8187H1e5G9AP0QQ5B60HbA=
|
||||
github.com/grafana/authlib/types v0.0.0-20250219092154-21ce22b49f31/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 h1:DnRUYiAotHXnrfYJCvhH1NkiyWVcPm5Pd+P7Ugqt/d8=
|
||||
github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82/go.mod h1:qYjSd1tmJiuVoSICp7Py9/zD54O9uQQA3wuM6Gg4DFM=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0 h1:K/P/bm7Cp7Di4tqIJ3EQz2+842JozQGRaz62r95ApME=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240701135906-559738ce6ae1 h1:ItDcDxUjVLPKja+hogpqgW/kj8LxUL2qscelXIsN1Bs=
|
||||
@@ -312,8 +312,8 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
@@ -26,8 +26,18 @@ var (
|
||||
_ rest.SingularNameProvider = (DualWriter)(nil)
|
||||
)
|
||||
|
||||
type dualWriteContextKey struct{}
|
||||
|
||||
func IsDualWriteUpdate(ctx context.Context) bool {
|
||||
return ctx.Value(dualWriteContextKey{}) == true
|
||||
}
|
||||
|
||||
func WithDualWriteUpdate(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, dualWriteContextKey{}, true)
|
||||
}
|
||||
|
||||
// Function that will create a dual writer
|
||||
type DualWriteBuilder func(gr schema.GroupResource, legacy LegacyStorage, storage Storage) (Storage, error)
|
||||
type DualWriteBuilder func(gr schema.GroupResource, legacy Storage, unified Storage) (Storage, error)
|
||||
|
||||
// Storage is a storage implementation that satisfies the same interfaces as genericregistry.Store.
|
||||
type Storage interface {
|
||||
@@ -36,26 +46,12 @@ type Storage interface {
|
||||
rest.TableConvertor
|
||||
rest.SingularNameProvider
|
||||
rest.Getter
|
||||
// TODO: when watch is implemented, we can replace all the below with rest.StandardStorage
|
||||
rest.Lister
|
||||
rest.CreaterUpdater
|
||||
rest.GracefulDeleter
|
||||
rest.CollectionDeleter
|
||||
}
|
||||
|
||||
// LegacyStorage is a storage implementation that writes to the Grafana SQL database.
|
||||
type LegacyStorage interface {
|
||||
rest.Storage
|
||||
rest.Scoper
|
||||
rest.SingularNameProvider
|
||||
rest.CreaterUpdater
|
||||
rest.Lister
|
||||
rest.GracefulDeleter
|
||||
rest.CollectionDeleter
|
||||
rest.TableConvertor
|
||||
rest.Getter
|
||||
}
|
||||
|
||||
// DualWriter is a storage implementation that writes first to LegacyStorage and then to Storage.
|
||||
// If writing to LegacyStorage fails, the write to Storage is skipped and the error is returned.
|
||||
// Storage is used for all read operations. This is useful as a migration step from SQL based
|
||||
@@ -79,7 +75,6 @@ type LegacyStorage interface {
|
||||
|
||||
type DualWriter interface {
|
||||
Storage
|
||||
LegacyStorage
|
||||
Mode() DualWriterMode
|
||||
}
|
||||
|
||||
@@ -110,8 +105,8 @@ const (
|
||||
// NewDualWriter returns a new DualWriter.
|
||||
func NewDualWriter(
|
||||
mode DualWriterMode,
|
||||
legacy LegacyStorage,
|
||||
storage Storage,
|
||||
legacy Storage,
|
||||
unified Storage,
|
||||
reg prometheus.Registerer,
|
||||
resource string,
|
||||
) Storage {
|
||||
@@ -122,17 +117,17 @@ func NewDualWriter(
|
||||
return legacy
|
||||
case Mode1:
|
||||
// read and write only from legacy storage
|
||||
return newDualWriterMode1(legacy, storage, metrics, resource)
|
||||
return newDualWriterMode1(legacy, unified, metrics, resource)
|
||||
case Mode2:
|
||||
// write to both, read from storage but use legacy as backup
|
||||
return newDualWriterMode2(legacy, storage, metrics, resource)
|
||||
return newDualWriterMode2(legacy, unified, metrics, resource)
|
||||
case Mode3:
|
||||
// write to both, read from storage only
|
||||
return newDualWriterMode3(legacy, storage, metrics, resource)
|
||||
return newDualWriterMode3(legacy, unified, metrics, resource)
|
||||
case Mode4, Mode5:
|
||||
return storage
|
||||
return unified
|
||||
default:
|
||||
return newDualWriterMode1(legacy, storage, metrics, resource)
|
||||
return newDualWriterMode1(legacy, unified, metrics, resource)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
type DualWriterMode1 struct {
|
||||
Legacy LegacyStorage
|
||||
Legacy Storage
|
||||
Storage Storage
|
||||
*dualWriterMetrics
|
||||
resource string
|
||||
@@ -26,7 +26,7 @@ const mode1Str = "1"
|
||||
|
||||
// NewDualWriterMode1 returns a new DualWriter in mode 1.
|
||||
// Mode 1 represents writing to and reading from LegacyStorage.
|
||||
func newDualWriterMode1(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode1 {
|
||||
func newDualWriterMode1(legacy Storage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode1 {
|
||||
return &DualWriterMode1{
|
||||
Legacy: legacy,
|
||||
Storage: storage,
|
||||
|
||||
@@ -60,10 +60,10 @@ func TestMode1_Create(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -122,10 +122,10 @@ func TestMode1_CreateOnUnifiedStorage(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -190,10 +190,10 @@ func TestMode1_Get(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -251,10 +251,10 @@ func TestMode1_GetFromUnifiedStorage(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -308,10 +308,10 @@ func TestMode1_List(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -365,10 +365,10 @@ func TestMode1_ListFromUnifiedStorage(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -434,10 +434,10 @@ func TestMode1_Delete(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -494,10 +494,10 @@ func TestMode1_DeleteFromUnifiedStorage(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -565,10 +565,10 @@ func TestMode1_DeleteCollection(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -626,10 +626,10 @@ func TestMode1_DeleteCollectionFromUnifiedStorage(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -695,10 +695,10 @@ func TestMode1_Update(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -761,10 +761,10 @@ func TestMode1_UpdateOnUnifiedStorage(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
|
||||
@@ -16,15 +16,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
)
|
||||
|
||||
type dualWriteContextKey struct{}
|
||||
|
||||
func IsDualWriteUpdate(ctx context.Context) bool {
|
||||
return ctx.Value(dualWriteContextKey{}) == true
|
||||
}
|
||||
|
||||
type DualWriterMode2 struct {
|
||||
Storage Storage
|
||||
Legacy LegacyStorage
|
||||
Legacy Storage
|
||||
*dualWriterMetrics
|
||||
resource string
|
||||
Log klog.Logger
|
||||
@@ -35,7 +29,7 @@ const mode2Str = "2"
|
||||
// newDualWriterMode2 returns a new DualWriter in mode 2.
|
||||
// Mode 2 represents writing to LegacyStorage first, then to Storage.
|
||||
// When reading, values from LegacyStorage will be returned.
|
||||
func newDualWriterMode2(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode2 {
|
||||
func newDualWriterMode2(legacy Storage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode2 {
|
||||
return &DualWriterMode2{
|
||||
Legacy: legacy,
|
||||
Storage: storage,
|
||||
|
||||
@@ -54,10 +54,10 @@ func TestMode2_Create(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -138,10 +138,10 @@ func TestMode2_Get(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -212,10 +212,10 @@ func TestMode2_List(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -313,10 +313,10 @@ func TestMode2_Delete(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -382,10 +382,10 @@ func TestMode2_DeleteCollection(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -451,10 +451,10 @@ func TestMode2_Update(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
type DualWriterMode3 struct {
|
||||
Legacy LegacyStorage
|
||||
Legacy Storage
|
||||
Storage Storage
|
||||
watchImp rest.Watcher // watch is only available in mode 3 and 4
|
||||
*dualWriterMetrics
|
||||
@@ -27,7 +27,7 @@ type DualWriterMode3 struct {
|
||||
|
||||
// newDualWriterMode3 returns a new DualWriter in mode 3.
|
||||
// Mode 3 represents writing to LegacyStorage and Storage and reading from Storage.
|
||||
func newDualWriterMode3(legacy LegacyStorage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode3 {
|
||||
func newDualWriterMode3(legacy Storage, storage Storage, dwm *dualWriterMetrics, resource string) *DualWriterMode3 {
|
||||
return &DualWriterMode3{
|
||||
Legacy: legacy,
|
||||
Storage: storage,
|
||||
|
||||
@@ -61,10 +61,10 @@ func TestMode3_Create(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -128,10 +128,10 @@ func TestMode3_Get(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -187,10 +187,10 @@ func TestMode1_GetFromLegacyStorage(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -234,10 +234,10 @@ func TestMode3_List(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupStorageFn != nil {
|
||||
@@ -311,10 +311,10 @@ func TestMode3_Delete(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -380,10 +380,10 @@ func TestMode3_DeleteCollection(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -449,10 +449,10 @@ func TestMode3_Update(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
ls := legacyStoreMock{&mock.Mock{}, l}
|
||||
ls := storageMock{&mock.Mock{}, l}
|
||||
us := storageMock{&mock.Mock{}, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
|
||||
@@ -33,7 +33,7 @@ type SyncerConfig struct {
|
||||
RequestInfo *request.RequestInfo
|
||||
|
||||
Mode DualWriterMode
|
||||
LegacyStorage LegacyStorage
|
||||
LegacyStorage Storage
|
||||
Storage Storage
|
||||
ServerLockService ServerLockService
|
||||
|
||||
|
||||
@@ -181,12 +181,12 @@ func TestLegacyToUnifiedStorage_DataSyncer(t *testing.T) {
|
||||
// mode 1
|
||||
for _, tt := range tests {
|
||||
t.Run("Mode-1-"+tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
lm := &mock.Mock{}
|
||||
um := &mock.Mock{}
|
||||
|
||||
ls := legacyStoreMock{lm, l}
|
||||
ls := storageMock{lm, l}
|
||||
us := storageMock{um, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
@@ -221,12 +221,12 @@ func TestLegacyToUnifiedStorage_DataSyncer(t *testing.T) {
|
||||
// mode 2
|
||||
for _, tt := range tests {
|
||||
t.Run("Mode-2-"+tt.name, func(t *testing.T) {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
lm := &mock.Mock{}
|
||||
um := &mock.Mock{}
|
||||
|
||||
ls := legacyStoreMock{lm, l}
|
||||
ls := storageMock{lm, l}
|
||||
us := storageMock{um, s}
|
||||
|
||||
if tt.setupLegacyFn != nil {
|
||||
|
||||
@@ -64,7 +64,7 @@ func TestSetDualWritingMode(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
l := (LegacyStorage)(nil)
|
||||
l := (Storage)(nil)
|
||||
s := (Storage)(nil)
|
||||
|
||||
sm := &mock.Mock{}
|
||||
@@ -75,7 +75,7 @@ func TestSetDualWritingMode(t *testing.T) {
|
||||
|
||||
lm := &mock.Mock{}
|
||||
lm.On("List", mock.Anything, mock.Anything).Return(exampleList, nil)
|
||||
ls := legacyStoreMock{lm, l}
|
||||
ls := storageMock{lm, l}
|
||||
|
||||
serverLockSvc := &fakeServerLock{
|
||||
err: tt.serverLockError,
|
||||
|
||||
@@ -11,102 +11,11 @@ import (
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
)
|
||||
|
||||
type legacyStoreMock struct {
|
||||
*mock.Mock
|
||||
LegacyStorage
|
||||
}
|
||||
|
||||
type storageMock struct {
|
||||
*mock.Mock
|
||||
Storage
|
||||
}
|
||||
|
||||
func (m legacyStoreMock) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, errors.New("context canceled")
|
||||
default:
|
||||
}
|
||||
|
||||
args := m.Called(ctx, name, options)
|
||||
if err := args.Get(1); err != nil {
|
||||
return nil, err.(error)
|
||||
}
|
||||
return args.Get(0).(runtime.Object), args.Error(1)
|
||||
}
|
||||
|
||||
func (m legacyStoreMock) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, errors.New("context canceled")
|
||||
default:
|
||||
}
|
||||
|
||||
args := m.Called(ctx, obj, createValidation, options)
|
||||
if err := args.Get(1); err != nil {
|
||||
return nil, err.(error)
|
||||
}
|
||||
return args.Get(0).(runtime.Object), args.Error(1)
|
||||
}
|
||||
|
||||
func (m legacyStoreMock) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, errors.New("context canceled")
|
||||
default:
|
||||
}
|
||||
|
||||
args := m.Called(ctx, options)
|
||||
if err := args.Get(1); err != nil {
|
||||
return nil, err.(error)
|
||||
}
|
||||
return args.Get(0).(runtime.Object), args.Error(1)
|
||||
}
|
||||
|
||||
func (m legacyStoreMock) NewList() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m legacyStoreMock) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, false, errors.New("context canceled")
|
||||
default:
|
||||
}
|
||||
args := m.Called(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options)
|
||||
if err := args.Get(2); err != nil {
|
||||
return nil, false, err.(error)
|
||||
}
|
||||
return args.Get(0).(runtime.Object), args.Bool(1), args.Error(2)
|
||||
}
|
||||
|
||||
func (m legacyStoreMock) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, false, errors.New("context canceled")
|
||||
default:
|
||||
}
|
||||
|
||||
args := m.Called(ctx, name, deleteValidation, options)
|
||||
if err := args.Get(2); err != nil {
|
||||
return nil, false, err.(error)
|
||||
}
|
||||
return args.Get(0).(runtime.Object), args.Bool(1), args.Error(2)
|
||||
}
|
||||
|
||||
func (m legacyStoreMock) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, errors.New("context canceled")
|
||||
default:
|
||||
}
|
||||
args := m.Called(ctx, deleteValidation, options, listOptions)
|
||||
if err := args.Get(1); err != nil {
|
||||
return nil, err.(error)
|
||||
}
|
||||
return args.Get(0).(runtime.Object), args.Error(1)
|
||||
}
|
||||
|
||||
// Unified Store
|
||||
func (m storageMock) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
||||
select {
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ require (
|
||||
github.com/docker/docker v27.4.1+incompatible // @grafana/grafana-developer-enablement-squad
|
||||
github.com/drone/drone-cli v1.8.0 // @grafana/grafana-developer-enablement-squad
|
||||
github.com/gogo/protobuf v1.3.2 // indirect; @grafana/alerting-backend
|
||||
github.com/google/go-cmp v0.6.0 // @grafana/grafana-backend-group
|
||||
github.com/google/go-cmp v0.7.0 // @grafana/grafana-backend-group
|
||||
github.com/google/go-github/v69 v69.2.0 // @grafana/grafana-developer-enablement-squad
|
||||
github.com/google/uuid v1.6.0 // indirect; @grafana/grafana-backend-group
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 // indirect; @grafana/grafana-backend-group
|
||||
@@ -35,7 +35,7 @@ require (
|
||||
golang.org/x/time v0.9.0 // indirect; @grafana/grafana-backend-group
|
||||
google.golang.org/api v0.216.0 // @grafana/grafana-backend-group
|
||||
google.golang.org/grpc v1.70.0 // indirect; @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.36.4 // indirect; @grafana/plugins-platform-backend
|
||||
google.golang.org/protobuf v1.36.5 // indirect; @grafana/plugins-platform-backend
|
||||
gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-backend
|
||||
)
|
||||
|
||||
|
||||
+4
-4
@@ -126,8 +126,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE=
|
||||
github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
@@ -362,8 +362,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -3,7 +3,7 @@ module github.com/grafana/grafana/pkg/build/wire
|
||||
go 1.23.1
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/google/subcommands v1.2.0
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
|
||||
golang.org/x/tools v0.29.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ require (
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/golang/glog v1.2.4 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
|
||||
+2
-2
@@ -25,8 +25,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
|
||||
github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
|
||||
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grafana/codejen v0.0.4-0.20230321061741-77f656893a3d h1:hrXbGJ5jgp6yNITzs5o+zXq0V5yT3siNJ+uM8LGwWKk=
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//go:build enterprise
|
||||
// +build enterprise
|
||||
|
||||
package extensions
|
||||
|
||||
import (
|
||||
_ "cloud.google.com/go/kms/apiv1"
|
||||
_ "cloud.google.com/go/kms/apiv1/kmspb"
|
||||
_ "cloud.google.com/go/spanner"
|
||||
_ "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
_ "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys"
|
||||
_ "github.com/Azure/azure-sdk-for-go/services/keyvault/v7.1/keyvault"
|
||||
_ "github.com/Azure/go-autorest/autorest"
|
||||
_ "github.com/Azure/go-autorest/autorest/adal"
|
||||
_ "github.com/beevik/etree"
|
||||
_ "github.com/blugelabs/bluge"
|
||||
_ "github.com/blugelabs/bluge_segment_api"
|
||||
_ "github.com/crewjam/saml"
|
||||
_ "github.com/go-jose/go-jose/v3"
|
||||
_ "github.com/gobwas/glob"
|
||||
_ "github.com/googleapis/gax-go/v2"
|
||||
_ "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus"
|
||||
_ "github.com/grpc-ecosystem/go-grpc-middleware/v2"
|
||||
_ "github.com/hashicorp/go-multierror"
|
||||
_ "github.com/hashicorp/golang-lru/v2"
|
||||
_ "github.com/m3db/prometheus_remote_client_golang/promremote"
|
||||
_ "github.com/phpdave11/gofpdi"
|
||||
_ "github.com/robfig/cron/v3"
|
||||
_ "github.com/russellhaering/goxmldsig"
|
||||
_ "github.com/spf13/cobra" // used by the standalone apiserver cli
|
||||
_ "github.com/stretchr/testify/require"
|
||||
_ "golang.org/x/time/rate"
|
||||
_ "xorm.io/builder"
|
||||
|
||||
_ "github.com/grafana/dskit/backoff"
|
||||
_ "github.com/grafana/dskit/flagext"
|
||||
_ "github.com/grafana/e2e"
|
||||
_ "github.com/grafana/gofpdf"
|
||||
_ "github.com/grafana/gomemcache/memcache"
|
||||
)
|
||||
+1
-34
@@ -1,38 +1,5 @@
|
||||
package extensions
|
||||
|
||||
import (
|
||||
_ "cloud.google.com/go/kms/apiv1"
|
||||
_ "cloud.google.com/go/kms/apiv1/kmspb"
|
||||
_ "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
_ "github.com/Azure/azure-sdk-for-go/sdk/keyvault/azkeys"
|
||||
_ "github.com/Azure/azure-sdk-for-go/services/keyvault/v7.1/keyvault"
|
||||
_ "github.com/Azure/go-autorest/autorest"
|
||||
_ "github.com/Azure/go-autorest/autorest/adal"
|
||||
_ "github.com/beevik/etree"
|
||||
_ "github.com/blugelabs/bluge"
|
||||
_ "github.com/blugelabs/bluge_segment_api"
|
||||
_ "github.com/crewjam/saml"
|
||||
_ "github.com/go-jose/go-jose/v3"
|
||||
_ "github.com/gobwas/glob"
|
||||
_ "github.com/googleapis/gax-go/v2"
|
||||
_ "github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus"
|
||||
_ "github.com/grpc-ecosystem/go-grpc-middleware/v2"
|
||||
_ "github.com/hashicorp/go-multierror"
|
||||
_ "github.com/hashicorp/golang-lru/v2"
|
||||
_ "github.com/m3db/prometheus_remote_client_golang/promremote"
|
||||
_ "github.com/phpdave11/gofpdi"
|
||||
_ "github.com/robfig/cron/v3"
|
||||
_ "github.com/russellhaering/goxmldsig"
|
||||
_ "github.com/spf13/cobra" // used by the standalone apiserver cli
|
||||
_ "github.com/stretchr/testify/require"
|
||||
_ "golang.org/x/time/rate"
|
||||
_ "xorm.io/builder"
|
||||
|
||||
_ "github.com/grafana/dskit/backoff"
|
||||
_ "github.com/grafana/dskit/flagext"
|
||||
_ "github.com/grafana/e2e"
|
||||
_ "github.com/grafana/gofpdf"
|
||||
_ "github.com/grafana/gomemcache/memcache"
|
||||
)
|
||||
// Imports used by Grafana enterprise are in enterprise_imports.go (behind a build tag).
|
||||
|
||||
var IsEnterprise bool = false
|
||||
|
||||
@@ -16,7 +16,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/authn"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
@@ -138,9 +137,7 @@ func CanAdminPlugins(cfg *setting.Cfg, accessControl ac.AccessControl) func(c *c
|
||||
}
|
||||
}
|
||||
|
||||
func RoleAppPluginAuth(accessControl ac.AccessControl, ps pluginstore.Store, features featuremgmt.FeatureToggles,
|
||||
logger log.Logger,
|
||||
) func(c *contextmodel.ReqContext) {
|
||||
func RoleAppPluginAuth(accessControl ac.AccessControl, ps pluginstore.Store, logger log.Logger) func(c *contextmodel.ReqContext) {
|
||||
return func(c *contextmodel.ReqContext) {
|
||||
pluginID := web.Params(c.Req)[":id"]
|
||||
p, exists := ps.Plugin(c.Req.Context(), pluginID)
|
||||
@@ -164,12 +161,11 @@ func RoleAppPluginAuth(accessControl ac.AccessControl, ps pluginstore.Store, fea
|
||||
}
|
||||
|
||||
if normalizeIncludePath(u.Path) == path {
|
||||
useRBAC := features.IsEnabledGlobally(featuremgmt.FlagAccessControlOnCall) && i.RequiresRBACAction()
|
||||
if useRBAC && !hasAccess(pluginaccesscontrol.GetPluginRouteEvaluator(pluginID, i.Action)) {
|
||||
if i.RequiresRBACAction() && !hasAccess(pluginaccesscontrol.GetPluginRouteEvaluator(pluginID, i.Action)) {
|
||||
logger.Debug("Plugin include is covered by RBAC, user doesn't have access", "plugin", pluginID, "include", i.Name)
|
||||
permitted = false
|
||||
break
|
||||
} else if !useRBAC && !c.HasUserRole(i.Role) {
|
||||
} else if !i.RequiresRBACAction() && !c.HasUserRole(i.Role) {
|
||||
permitted = false
|
||||
break
|
||||
}
|
||||
|
||||
@@ -204,11 +204,10 @@ func TestRoleAppPluginAuth(t *testing.T) {
|
||||
0: tc.role,
|
||||
},
|
||||
})
|
||||
features := featuremgmt.WithFeatures()
|
||||
logger := &logtest.Fake{}
|
||||
ac := &actest.FakeAccessControl{}
|
||||
|
||||
sc.m.Get("/a/:id/*", RoleAppPluginAuth(ac, ps, features, logger), func(c *contextmodel.ReqContext) {
|
||||
sc.m.Get("/a/:id/*", RoleAppPluginAuth(ac, ps, logger), func(c *contextmodel.ReqContext) {
|
||||
c.JSON(http.StatusOK, map[string]interface{}{})
|
||||
})
|
||||
sc.fakeReq("GET", path).exec()
|
||||
@@ -227,10 +226,9 @@ func TestRoleAppPluginAuth(t *testing.T) {
|
||||
0: org.RoleViewer,
|
||||
},
|
||||
})
|
||||
features := featuremgmt.WithFeatures()
|
||||
logger := &logtest.Fake{}
|
||||
ac := &actest.FakeAccessControl{}
|
||||
sc.m.Get("/a/:id/*", RoleAppPluginAuth(ac, &pluginstore.FakePluginStore{}, features, logger), func(c *contextmodel.ReqContext) {
|
||||
sc.m.Get("/a/:id/*", RoleAppPluginAuth(ac, &pluginstore.FakePluginStore{}, logger), func(c *contextmodel.ReqContext) {
|
||||
c.JSON(http.StatusOK, map[string]interface{}{})
|
||||
})
|
||||
sc.fakeReq("GET", "/a/test-app/test").exec()
|
||||
@@ -245,7 +243,6 @@ func TestRoleAppPluginAuth(t *testing.T) {
|
||||
0: org.RoleViewer,
|
||||
},
|
||||
})
|
||||
features := featuremgmt.WithFeatures()
|
||||
logger := &logtest.Fake{}
|
||||
ac := &actest.FakeAccessControl{}
|
||||
sc.m.Get("/a/:id/*", RoleAppPluginAuth(ac, pluginstore.NewFakePluginStore(pluginstore.Plugin{
|
||||
@@ -259,7 +256,7 @@ func TestRoleAppPluginAuth(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
}), features, logger), func(c *contextmodel.ReqContext) {
|
||||
}), logger), func(c *contextmodel.ReqContext) {
|
||||
c.JSON(http.StatusOK, map[string]interface{}{})
|
||||
})
|
||||
sc.fakeReq("GET", "/a/test-app/notExistingPath").exec()
|
||||
@@ -307,7 +304,6 @@ func TestRoleAppPluginAuth(t *testing.T) {
|
||||
},
|
||||
})
|
||||
logger := &logtest.Fake{}
|
||||
features := featuremgmt.WithFeatures(featuremgmt.FlagAccessControlOnCall)
|
||||
ac := &actest.FakeAccessControl{
|
||||
ExpectedEvaluate: tc.evalResult,
|
||||
ExpectedErr: tc.evalErr,
|
||||
@@ -327,7 +323,7 @@ func TestRoleAppPluginAuth(t *testing.T) {
|
||||
},
|
||||
})
|
||||
|
||||
sc.m.Get("/a/:id/*", RoleAppPluginAuth(ac, ps, features, logger), func(c *contextmodel.ReqContext) {
|
||||
sc.m.Get("/a/:id/*", RoleAppPluginAuth(ac, ps, logger), func(c *contextmodel.ReqContext) {
|
||||
c.JSON(http.StatusOK, map[string]interface{}{})
|
||||
})
|
||||
sc.fakeReq("GET", path).exec()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user