Merge remote-tracking branch 'origin/main' into grafana-git-ui-sync
This commit is contained in:
150 files changed
+3478
-1498
No files matched your search
+5
-6
@@ -830,7 +830,8 @@ exports[`better eslint`] = {
|
||||
],
|
||||
"packages/grafana-ui/src/components/Table/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Table/utils.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
@@ -4827,7 +4828,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
|
||||
],
|
||||
"public/app/features/explore/PrometheusListView/RawListItem.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()", "0"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
|
||||
],
|
||||
"public/app/features/explore/PrometheusListView/RawListItemAttributes.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
|
||||
@@ -7480,10 +7483,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
],
|
||||
"public/app/plugins/datasource/grafana/components/TimePickerInput.tsx:5381": [
|
||||
[0, 0, 0, "\'@grafana/ui/src/components/Forms/commonStyles\' import is restricted from being used by a pattern. Import from the public export instead.", "0"],
|
||||
[0, 0, 0, "\'@grafana/ui/src/themes/mixins\' import is restricted from being used by a pattern. Import from the public export instead.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/grafana/components/TimeRegionEditor.tsx:5381": [
|
||||
[0, 0, 0, "\'@grafana/ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneOffset\' import is restricted from being used by a pattern. Import from the public export instead.", "0"],
|
||||
[0, 0, 0, "\'@grafana/ui/src/components/DateTimePickers/TimeZonePicker/TimeZoneTitle\' import is restricted from being used by a pattern. Import from the public export instead.", "1"]
|
||||
|
||||
+105
-105
@@ -25,7 +25,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build verify-drone
|
||||
@@ -75,7 +75,7 @@ steps:
|
||||
- go install github.com/bazelbuild/buildtools/buildifier@latest
|
||||
- buildifier --lint=warn -mode=check -r .
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: lint-starlark
|
||||
trigger:
|
||||
event:
|
||||
@@ -427,7 +427,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -436,21 +436,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -459,7 +459,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
event:
|
||||
@@ -513,7 +513,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $(/usr/bin/github-app-external-token) > /github-app/token
|
||||
@@ -558,16 +558,16 @@ steps:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- go run scripts/modowners/modowners.go check go.mod
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: validate-modfile
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make swagger-validate
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: validate-openapi-spec
|
||||
trigger:
|
||||
event:
|
||||
@@ -643,7 +643,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -653,7 +653,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -662,7 +662,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -698,7 +698,7 @@ steps:
|
||||
- /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64
|
||||
-a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu
|
||||
-a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7
|
||||
-a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.4 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
-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.3
|
||||
--tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{
|
||||
.version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD
|
||||
@@ -1096,7 +1096,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
@@ -1110,7 +1110,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -1119,14 +1119,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -1147,7 +1147,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -1168,7 +1168,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -1184,7 +1184,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -1200,7 +1200,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -1216,7 +1216,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
event:
|
||||
@@ -1298,7 +1298,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
trigger:
|
||||
event:
|
||||
@@ -1419,7 +1419,7 @@ steps:
|
||||
&& return 1; fi
|
||||
depends_on:
|
||||
- clone-enterprise
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: swagger-gen
|
||||
trigger:
|
||||
event:
|
||||
@@ -1524,7 +1524,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -1535,7 +1535,7 @@ steps:
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on:
|
||||
- clone-enterprise
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -1545,14 +1545,14 @@ steps:
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on:
|
||||
- clone-enterprise
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1560,7 +1560,7 @@ steps:
|
||||
- go test -v -run=^$ -benchmem -timeout=1h -count=8 -bench=. ${GO_PACKAGES}
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: sqlite-benchmark-integration-tests
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1572,7 +1572,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: postgres-benchmark-integration-tests
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1583,7 +1583,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: mysql-8.0-benchmark-integration-tests
|
||||
trigger:
|
||||
event:
|
||||
@@ -1655,7 +1655,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
trigger:
|
||||
branch: main
|
||||
@@ -1828,7 +1828,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -1837,21 +1837,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -1860,7 +1860,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
branch: main
|
||||
@@ -1905,22 +1905,22 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- go run scripts/modowners/modowners.go check go.mod
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: validate-modfile
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make swagger-validate
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: validate-openapi-spec
|
||||
- commands:
|
||||
- ./bin/build verify-drone
|
||||
@@ -2052,7 +2052,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- '# It is required that code generated from Thema/CUE be committed and in sync
|
||||
@@ -2062,7 +2062,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -2071,7 +2071,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -2106,7 +2106,7 @@ steps:
|
||||
- /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64
|
||||
-a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu
|
||||
-a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7
|
||||
-a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.4 --yarn-cache=$$YARN_CACHE_FOLDER
|
||||
-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.3
|
||||
--tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{
|
||||
.version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD
|
||||
@@ -2581,7 +2581,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
@@ -2595,7 +2595,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -2604,14 +2604,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -2632,7 +2632,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -2653,7 +2653,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -2669,7 +2669,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -2685,7 +2685,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -2701,7 +2701,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
branch: main
|
||||
@@ -2960,7 +2960,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -2969,21 +2969,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -2992,7 +2992,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
branch:
|
||||
@@ -3035,22 +3035,22 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- go run scripts/modowners/modowners.go check go.mod
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: validate-modfile
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make swagger-validate
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: validate-openapi-spec
|
||||
trigger:
|
||||
branch:
|
||||
@@ -3129,7 +3129,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- echo $DRONE_RUNNER_NAME
|
||||
@@ -3143,7 +3143,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -3152,14 +3152,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -3180,7 +3180,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -3201,7 +3201,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -3217,7 +3217,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -3233,7 +3233,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -3249,7 +3249,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
branch:
|
||||
@@ -3349,7 +3349,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build artifacts docker fetch --edition oss
|
||||
@@ -3481,7 +3481,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build artifacts docker fetch --edition oss
|
||||
@@ -3622,7 +3622,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build artifacts packages --artifacts-editions=oss --tag $${DRONE_TAG} --src-bucket
|
||||
@@ -3714,7 +3714,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- yarn install --immutable || yarn install --immutable
|
||||
@@ -3814,7 +3814,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- depends_on:
|
||||
- compile-build-cmd
|
||||
@@ -3911,7 +3911,7 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build publish grafana-com --edition oss ${DRONE_TAG}
|
||||
@@ -3973,7 +3973,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.4
|
||||
GO_VERSION: 1.23.5
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4048,7 +4048,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.4
|
||||
GO_VERSION: 1.23.5
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4105,13 +4105,13 @@ steps:
|
||||
depends_on: []
|
||||
environment:
|
||||
CGO_ENABLED: 0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: compile-build-cmd
|
||||
- commands:
|
||||
- ./bin/build whatsnew-checker
|
||||
depends_on:
|
||||
- compile-build-cmd
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: whats-new-checker
|
||||
trigger:
|
||||
event:
|
||||
@@ -4210,7 +4210,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.4
|
||||
GO_VERSION: 1.23.5
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4361,7 +4361,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -4370,21 +4370,21 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- apk add --update build-base shared-mime-info shared-mime-info-lang
|
||||
- go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend
|
||||
- commands:
|
||||
- apk add --update build-base
|
||||
@@ -4393,7 +4393,7 @@ steps:
|
||||
| grep -o '\(.*\)/' | sort -u)
|
||||
depends_on:
|
||||
- wire-install
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: test-backend-integration
|
||||
trigger:
|
||||
cron:
|
||||
@@ -4447,7 +4447,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.4
|
||||
GO_VERSION: 1.23.5
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4591,7 +4591,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.4
|
||||
GO_VERSION: 1.23.5
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4698,7 +4698,7 @@ steps:
|
||||
- export GITHUB_TOKEN=$(cat /github-app/token)
|
||||
- 'dagger run --silent /src/grafana-build artifacts -a $${ARTIFACTS} --grafana-ref=$${GRAFANA_REF}
|
||||
--enterprise-ref=$${ENTERPRISE_REF} --grafana-repo=$${GRAFANA_REPO} --version=$${VERSION} '
|
||||
- --go-version=1.23.4
|
||||
- --go-version=1.23.5
|
||||
depends_on:
|
||||
- github-app-generate-token
|
||||
environment:
|
||||
@@ -4719,7 +4719,7 @@ steps:
|
||||
from_secret: grafana_api_key
|
||||
GCP_KEY_BASE64:
|
||||
from_secret: gcp_key_base64
|
||||
GO_VERSION: 1.23.4
|
||||
GO_VERSION: 1.23.5
|
||||
GPG_PASSPHRASE:
|
||||
from_secret: packages_gpg_passphrase
|
||||
GPG_PRIVATE_KEY:
|
||||
@@ -4853,7 +4853,7 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-cue
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-cue
|
||||
- commands:
|
||||
- '# It is required that generated jsonnet is committed and in sync with its inputs.'
|
||||
@@ -4862,14 +4862,14 @@ steps:
|
||||
- apk add --update make
|
||||
- CODEGEN_VERIFY=1 make gen-jsonnet
|
||||
depends_on: []
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: verify-gen-jsonnet
|
||||
- commands:
|
||||
- apk add --update make
|
||||
- make gen-go
|
||||
depends_on:
|
||||
- verify-gen-cue
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: wire-install
|
||||
- commands:
|
||||
- dockerize -wait tcp://postgres:5432 -timeout 120s
|
||||
@@ -4890,7 +4890,7 @@ steps:
|
||||
GRAFANA_TEST_DB: postgres
|
||||
PGPASSWORD: grafanatest
|
||||
POSTGRES_HOST: postgres
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: postgres-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mysql80:3306 -timeout 120s
|
||||
@@ -4911,7 +4911,7 @@ steps:
|
||||
environment:
|
||||
GRAFANA_TEST_DB: mysql
|
||||
MYSQL_HOST: mysql80
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: mysql-8.0-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://redis:6379 -timeout 120s
|
||||
@@ -4927,7 +4927,7 @@ steps:
|
||||
- wait-for-redis
|
||||
environment:
|
||||
REDIS_URL: redis://redis:6379/0
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: redis-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://memcached:11211 -timeout 120s
|
||||
@@ -4943,7 +4943,7 @@ steps:
|
||||
- wait-for-memcached
|
||||
environment:
|
||||
MEMCACHED_HOSTS: memcached:11211
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: memcached-integration-tests
|
||||
- commands:
|
||||
- dockerize -wait tcp://mimir_backend:8080 -timeout 120s
|
||||
@@ -4959,7 +4959,7 @@ steps:
|
||||
environment:
|
||||
AM_TENANT_ID: test
|
||||
AM_URL: http://mimir_backend:8080
|
||||
image: golang:1.23.4-alpine
|
||||
image: golang:1.23.5-alpine
|
||||
name: remote-alertmanager-integration-tests
|
||||
trigger:
|
||||
event:
|
||||
@@ -5262,7 +5262,7 @@ steps:
|
||||
- commands:
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM docker:27-cli
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine/git:2.40.1
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.23.4-alpine
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.23.5-alpine
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22.11.0-alpine
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22-bookworm
|
||||
- trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM google/cloud-sdk:431.0.0
|
||||
@@ -5300,7 +5300,7 @@ steps:
|
||||
- commands:
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL docker:27-cli
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL alpine/git:2.40.1
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.23.4-alpine
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.23.5-alpine
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL node:22.11.0-alpine
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL node:22-bookworm
|
||||
- trivy --exit-code 1 --severity HIGH,CRITICAL google/cloud-sdk:431.0.0
|
||||
@@ -5569,6 +5569,6 @@ kind: secret
|
||||
name: gcr_credentials
|
||||
---
|
||||
kind: signature
|
||||
hmac: be82e983dfa15f85f82935674ec109056f519ff99c7ab1f4be71f9ce62b571a7
|
||||
hmac: 154c1f072294cef09ba4f579eed30b1e29bc5c263897c862f4574432d321502c
|
||||
|
||||
...
|
||||
@@ -13,10 +13,6 @@ packageExtensions:
|
||||
doctrine@3.0.0:
|
||||
dependencies:
|
||||
assert: 2.0.0
|
||||
rc-time-picker@3.7.3:
|
||||
peerDependencies:
|
||||
react: 17.0.1
|
||||
react-dom: 17.0.1
|
||||
rc-trigger@2.6.5:
|
||||
peerDependencies:
|
||||
react: 17.0.1
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
ARG BASE_IMAGE=alpine:3.20
|
||||
ARG JS_IMAGE=node:22-alpine
|
||||
ARG JS_PLATFORM=linux/amd64
|
||||
ARG GO_IMAGE=golang:1.23.4-alpine
|
||||
ARG GO_IMAGE=golang:1.23.5-alpine
|
||||
|
||||
ARG GO_SRC=go-builder
|
||||
ARG JS_SRC=js-builder
|
||||
|
||||
@@ -8,7 +8,7 @@ WIRE_TAGS = "oss"
|
||||
include .bingo/Variables.mk
|
||||
|
||||
GO = go
|
||||
GO_VERSION = 1.23.4
|
||||
GO_VERSION = 1.23.5
|
||||
GO_LINT_FILES ?= $(shell ./scripts/go-workspace/golangci-lint-includes.sh)
|
||||
GO_TEST_FILES ?= $(shell ./scripts/go-workspace/test-includes.sh)
|
||||
SH_FILES ?= $(shell find ./scripts -name *.sh)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/alerting/notifications
|
||||
|
||||
go 1.23.4
|
||||
go 1.23.5
|
||||
|
||||
replace github.com/grafana/grafana => ../../..
|
||||
|
||||
@@ -38,7 +38,7 @@ require (
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20240821155123-6891eb1d35da // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmespath-community/go-jmespath v1.1.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -69,7 +69,7 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
@@ -80,7 +80,7 @@ require (
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
|
||||
@@ -81,8 +81,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jmespath-community/go-jmespath v1.1.1 h1:bFikPhsi/FdmlZhVgSCd2jj1e7G/rw+zyQfyg5UF+L4=
|
||||
@@ -196,8 +196,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
@@ -262,8 +262,8 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
|
||||
@@ -32,7 +32,7 @@ require (
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/invopop/yaml v0.3.1 // indirect
|
||||
@@ -60,7 +60,7 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/oauth2 v0.25.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
@@ -70,7 +70,7 @@ require (
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
|
||||
@@ -53,8 +53,8 @@ github.com/grafana/grafana-app-sdk v0.29.0 h1:LMSm/+0LOBPd13fe1bs/4sKJmuLiixYUX9
|
||||
github.com/grafana/grafana-app-sdk v0.29.0/go.mod h1:XLt308EmK6kvqPlzjUyXxbwZKEk2vur/eiypUNDay5I=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0 h1:mgbXaAf33aFwqwGVeaX30l8rkeAJH0iACgX5Rn6YkN4=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -140,8 +140,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -187,8 +187,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||
|
||||
@@ -33,7 +33,7 @@ require (
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/invopop/yaml v0.3.1 // indirect
|
||||
@@ -61,7 +61,7 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
golang.org/x/oauth2 v0.25.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
@@ -71,7 +71,7 @@ require (
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
|
||||
@@ -53,8 +53,8 @@ github.com/grafana/grafana-app-sdk v0.29.0 h1:LMSm/+0LOBPd13fe1bs/4sKJmuLiixYUX9
|
||||
github.com/grafana/grafana-app-sdk v0.29.0/go.mod h1:XLt308EmK6kvqPlzjUyXxbwZKEk2vur/eiypUNDay5I=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0 h1:mgbXaAf33aFwqwGVeaX30l8rkeAJH0iACgX5Rn6YkN4=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.29.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
@@ -140,8 +140,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -187,8 +187,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||
|
||||
@@ -60,6 +60,14 @@ func main() {
|
||||
label: "label.with.spaß",
|
||||
getNextValue: staticList([]string{"this_is_fun"}),
|
||||
},
|
||||
{
|
||||
label: "instance",
|
||||
getNextValue: staticList([]string{"instance"}),
|
||||
},
|
||||
{
|
||||
label: "job",
|
||||
getNextValue: staticList([]string{"job"}),
|
||||
},
|
||||
{
|
||||
label: "site",
|
||||
getNextValue: staticList([]string{"LA-EPI"}),
|
||||
@@ -85,6 +93,12 @@ func main() {
|
||||
Help: "a metric with utf8 labels",
|
||||
}, dimensions)
|
||||
|
||||
target_info := promauto.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "target_info",
|
||||
Help: "an info metric model for otel",
|
||||
ConstLabels: map[string]string{"job": "job", "instance": "instance", "resource 1": "1", "resource 2": "2", "resource ę": "e", "deployment_environment": "prod"},
|
||||
})
|
||||
|
||||
http.Handle("/metrics", promhttp.Handler())
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
@@ -101,6 +115,7 @@ func main() {
|
||||
|
||||
utf8Metric.WithLabelValues(labels...).Inc()
|
||||
opsProcessed.WithLabelValues(labels...).Inc()
|
||||
target_info.Set(1)
|
||||
|
||||
time.Sleep(time.Second * 5)
|
||||
}
|
||||
|
||||
@@ -266,6 +266,7 @@ guaranteed because plugin developers can override this functionality. The follow
|
||||
- Datadog
|
||||
- Dataset
|
||||
- Druid
|
||||
- DynamoDB
|
||||
- GitHub
|
||||
- Google BigQuery
|
||||
- Grafana for YNAB
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana
|
||||
|
||||
go 1.23.4
|
||||
go 1.23.5
|
||||
|
||||
require (
|
||||
buf.build/gen/go/parca-dev/parca/connectrpc/go v1.17.0-20240902100956-02fd72488966.1 // @grafana/observability-traces-and-profiling
|
||||
@@ -94,7 +94,7 @@ require (
|
||||
github.com/grafana/tempo v1.5.1-0.20241001135150-ed943d7a56b2 // @grafana/observability-traces-and-profiling
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // @grafana/plugins-platform-backend
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 // @grafana/grafana-backend-group
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // @grafana/identity-access-team
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // @grafana/identity-access-team
|
||||
github.com/hashicorp/go-hclog v1.6.3 // @grafana/plugins-platform-backend
|
||||
github.com/hashicorp/go-multierror v1.1.1 // @grafana/alerting-squad
|
||||
github.com/hashicorp/go-plugin v1.6.2 // @grafana/plugins-platform-backend
|
||||
@@ -125,9 +125,9 @@ require (
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // @grafana/alerting-backend
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // @grafana/grafana-operator-experience-squad
|
||||
github.com/olekukonko/tablewriter v0.0.5 // @grafana/grafana-backend-group
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66 // @grafana/identity-access-team
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f // @grafana/identity-access-team
|
||||
github.com/openfga/openfga v1.6.2 // @grafana/identity-access-team
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5 // @grafana/identity-access-team
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c // @grafana/identity-access-team
|
||||
github.com/openfga/openfga v1.8.4 // @grafana/identity-access-team
|
||||
github.com/openzipkin/zipkin-go v0.4.3 // @grafana/oss-big-tent
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // @grafana/alerting-backend
|
||||
github.com/phpdave11/gofpdi v1.0.13 // @grafana/sharing-squad
|
||||
@@ -241,6 +241,7 @@ require (
|
||||
github.com/Masterminds/squirrel v1.5.4 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/RoaringBitmap/roaring v1.9.3 // indirect
|
||||
github.com/Yiling-J/theine-go v0.6.0 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
|
||||
@@ -327,7 +328,7 @@ require (
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.22.0 // indirect
|
||||
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/gofuzz v1.2.0 // indirect
|
||||
@@ -358,7 +359,7 @@ require (
|
||||
github.com/invopop/yaml v0.3.1 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.1 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.2 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
|
||||
@@ -373,7 +374,6 @@ require (
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect
|
||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||
github.com/karlseguin/ccache/v3 v3.0.5 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
@@ -424,7 +424,7 @@ require (
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/pressly/goose/v3 v3.22.1 // indirect
|
||||
github.com/pressly/goose/v3 v3.24.0 // indirect
|
||||
github.com/prometheus/common/sigv4 v0.1.0 // indirect
|
||||
github.com/prometheus/exporter-toolkit v0.13.2 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
@@ -480,8 +480,8 @@ require (
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.uber.org/mock v0.4.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
|
||||
go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
@@ -489,7 +489,7 @@ require (
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
@@ -503,7 +503,7 @@ require (
|
||||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.33.1 // indirect
|
||||
modernc.org/sqlite v1.34.4 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect
|
||||
|
||||
@@ -747,6 +747,8 @@ github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f h1:HR5nRmUQgX
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3HiCrHjHBdcm6E83vGaXh1KomZMA2P6aeo3hKx/wg0=
|
||||
github.com/Workiva/go-datastructures v1.1.5 h1:5YfhQ4ry7bZc2Mc7R0YZyYwpf5c6t1cEFvdAhd6Mkf4=
|
||||
github.com/Workiva/go-datastructures v1.1.5/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A=
|
||||
github.com/Yiling-J/theine-go v0.6.0 h1:jv7V/tcD6ijL0T4kfbJDKP81TCZBkoriNTPSqwivWuY=
|
||||
github.com/Yiling-J/theine-go v0.6.0/go.mod h1:mdch1vjgGWd7s3rWKvY+MF5InRLfRv/CWVI9RVNQ8wY=
|
||||
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
|
||||
@@ -1369,8 +1371,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g=
|
||||
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40=
|
||||
github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
@@ -1588,8 +1590,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
@@ -1710,8 +1712,8 @@ github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5ey
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
@@ -1775,8 +1777,6 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
|
||||
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karlseguin/ccache/v3 v3.0.5 h1:hFX25+fxzNjsRlREYsoGNa2LoVEw5mPF8wkWq/UnevQ=
|
||||
github.com/karlseguin/ccache/v3 v3.0.5/go.mod h1:qxC372+Qn+IBj8Pe3KvGjHPj0sWwEF7AeZVhsNPZ6uY=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
|
||||
@@ -2010,12 +2010,12 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66 h1:pAYrdyIKxPsMs/nRcTEnS9za2io11g7Rt7ng7HK82hk=
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66/go.mod h1:gil5LBD8tSdFQbUkCQdnXsoeU9kDJdJgbGdHkgJfcd0=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f h1:ZMZ7ntMnaHIPZxvVQv/aqC4ctzLqH+9Fqn4uw35kQpk=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f/go.mod h1:ll/hN6kS4EE6B/7J/PbZqac9Nuv7ZHpI+Jfh36JLrbs=
|
||||
github.com/openfga/openfga v1.6.2 h1:tHBAgiCPomCZb3IH0CFqOpTDVDA/Xb8kG87oX4JCbXc=
|
||||
github.com/openfga/openfga v1.6.2/go.mod h1:jzbEpheazf6MFjtanQt1rpxexSRzfa9057F7JlkMv2I=
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5 h1:z9jaRoo+NIN1AB0ogjtrjx1316TTuq6IbqpEg3UJycA=
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5/go.mod h1:m74TNgnAAIJ03gfHcx+xaRWnr+IbQy3y/AVNwwCFrC0=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c h1:1y84C0V4NRfPtRi4MqQ7+gnFtYgeBKPIeIAPLdVJ7j4=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c/go.mod h1:12RMe/HuRNyOzS33RQa53jwdcxE2znr8ycXMlVbgQN4=
|
||||
github.com/openfga/openfga v1.8.4 h1:OqyRpuxMCxcS7irTFYFkhAIYzmAnczNwxUqjnuZOQyo=
|
||||
github.com/openfga/openfga v1.8.4/go.mod h1:9Ax9VMMySV2JMsCT8MTePeYt4OrTnPAy1XUV1y9RyuU=
|
||||
github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg=
|
||||
github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo=
|
||||
github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
|
||||
@@ -2071,8 +2071,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/pressly/goose/v3 v3.22.1 h1:2zICEfr1O3yTP9BRZMGPj7qFxQ+ik6yeo+z1LMuioLc=
|
||||
github.com/pressly/goose/v3 v3.22.1/go.mod h1:xtMpbstWyCpyH+0cxLTMCENWBG+0CSxvTsXhW95d5eo=
|
||||
github.com/pressly/goose/v3 v3.24.0 h1:sFbNms7Bd++2VMq6HSgDHDLWa7kHz1qXzPb3ZIU72VU=
|
||||
github.com/pressly/goose/v3 v3.24.0/go.mod h1:rEWreU9uVtt0DHCyLzF9gRcWiiTF/V+528DV+4DORug=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
@@ -2466,16 +2466,16 @@ go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37Cb
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
@@ -3234,8 +3234,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
@@ -3447,8 +3447,8 @@ modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4=
|
||||
modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM=
|
||||
modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8=
|
||||
modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
go 1.23.4
|
||||
go 1.23.5
|
||||
|
||||
// The `skip:golangci-lint` comment tag is used to exclude the package from the `golangci-lint` GitHub Action.
|
||||
// The module at the root of the repo (`.`) is excluded because ./pkg/... is included manually in the `golangci-lint` configuration.
|
||||
|
||||
+146
@@ -1,5 +1,6 @@
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230802163732-1c33ebd9ecfa.1 h1:tdpHgTbmbvEIARu+bixzmleMi14+3imnpoFXz+Qzjp4=
|
||||
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230802163732-1c33ebd9ecfa.1/go.mod h1:xafc+XIsTxTy76GJQ1TKgvJWsSugFBqMaN27WhUblew=
|
||||
cel.dev/expr v0.16.2/go.mod h1:gXngZQMkWJoSbE8mOzehJlXQyubn/Vg0vR9/F3W7iw8=
|
||||
cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
@@ -8,6 +9,9 @@ cloud.google.com/go v0.110.9/go.mod h1:rpxevX/0Lqvlbc88b7Sc1SPNdyK1riNBTUU6JXhYN
|
||||
cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic=
|
||||
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
|
||||
cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4=
|
||||
cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms=
|
||||
cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
|
||||
cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc=
|
||||
cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68=
|
||||
cloud.google.com/go/accessapproval v1.7.2/go.mod h1:/gShiq9/kK/h8T/eEn1BTzalDvk0mZxJlhfw0p+Xuc0=
|
||||
cloud.google.com/go/accessapproval v1.7.3/go.mod h1:4l8+pwIxGTNqSf4T3ds8nLO94NQf0W/KnMNuQ9PbnP8=
|
||||
@@ -109,7 +113,13 @@ cloud.google.com/go/assuredworkloads v1.11.5/go.mod h1:FKJ3g3ZvkL2D7qtqIGnDufFkH
|
||||
cloud.google.com/go/assuredworkloads v1.12.1 h1:B+hWc62fYL8NdntPjx0rzJJ67qx99w6dCeIVDpHf7QE=
|
||||
cloud.google.com/go/assuredworkloads v1.12.1/go.mod h1:nBnkK2GZNSdtjU3ER75oC5fikub5/+QchbolKgnMI/I=
|
||||
cloud.google.com/go/auth v0.2.0/go.mod h1:+yb+oy3/P0geX6DLKlqiGHARGR6EX2GRtYCzWOCQSbU=
|
||||
cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w=
|
||||
cloud.google.com/go/auth v0.6.1/go.mod h1:eFHG7zDzbXHKmjJddFG/rBlcGp6t25SwRUiEQSlO4x4=
|
||||
cloud.google.com/go/auth v0.9.3/go.mod h1:7z6VY+7h3KUdRov5F1i8NDP5ZzWKYmEPO842BgCsmTk=
|
||||
cloud.google.com/go/auth v0.9.4/go.mod h1:SHia8n6//Ya940F1rLimhJCjjx7KE17t0ctFEci3HkA=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.0/go.mod h1:AfqujpDAlTfLfeCIl/HJZZlIxD8+nJoZ5e0x1IxGq5k=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
|
||||
cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE=
|
||||
cloud.google.com/go/automl v1.13.2/go.mod h1:gNY/fUmDEN40sP8amAX3MaXkxcqPIn7F1UIIPZpy4Mg=
|
||||
cloud.google.com/go/automl v1.13.3/go.mod h1:Y8KwvyAZFOsMAPqUCfNu1AyclbC6ivCUF/MTwORymyY=
|
||||
@@ -226,6 +236,8 @@ cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3
|
||||
cloud.google.com/go/compute v1.28.1 h1:XwPcZjgMCnU2tkwY10VleUjSAfpTj9RDn+kGrbYsi8o=
|
||||
cloud.google.com/go/compute v1.28.1/go.mod h1:b72iXMY4FucVry3NR3Li4kVyyTvbMDE7x5WsqvxjsYk=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
|
||||
cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
|
||||
cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM=
|
||||
cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM=
|
||||
cloud.google.com/go/contactcenterinsights v1.11.0/go.mod h1:hutBdImE4XNZ1NV4vbPJKSFOnQruhC5Lj9bZqWMTKiU=
|
||||
@@ -493,6 +505,8 @@ cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQy
|
||||
cloud.google.com/go/iam v1.1.4/go.mod h1:l/rg8l1AaA+VFMho/HYx2Vv6xinPSLMF8qfhRPIZ0L8=
|
||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||
cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
|
||||
cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE=
|
||||
cloud.google.com/go/iam v1.2.0/go.mod h1:zITGuWgsLZxd8OwAlX+eMFgZDXzBm7icj1PVTYG766Q=
|
||||
cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ=
|
||||
cloud.google.com/go/iap v1.9.0/go.mod h1:01OFxd1R+NFrg78S+hoPV5PxEzv22HXaNqUUlmNHFuY=
|
||||
cloud.google.com/go/iap v1.9.1/go.mod h1:SIAkY7cGMLohLSdBR25BuIxO+I4fXJiL06IBL7cy/5Q=
|
||||
@@ -550,6 +564,9 @@ cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUz
|
||||
cloud.google.com/go/longrunning v0.5.3/go.mod h1:y/0ga59EYu58J6SHmmQOvekvND2qODbu8ywBBW7EK7Y=
|
||||
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
|
||||
cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s=
|
||||
cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA=
|
||||
cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng=
|
||||
cloud.google.com/go/longrunning v0.6.0/go.mod h1:uHzSZqW89h7/pasCWNYdUpwGz3PcVWhrWupreVPYLts=
|
||||
cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak=
|
||||
cloud.google.com/go/managedidentities v1.6.2/go.mod h1:5c2VG66eCa0WIq6IylRk3TBW83l161zkFvCj28X7jn8=
|
||||
cloud.google.com/go/managedidentities v1.6.3/go.mod h1:tewiat9WLyFN0Fi7q1fDD5+0N4VUoL0SCX0OTCthZq4=
|
||||
@@ -839,6 +856,7 @@ cloud.google.com/go/speech v1.21.1/go.mod h1:E5GHZXYQlkqWQwY5xRSLHw2ci5NMQNG52Ff
|
||||
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/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
|
||||
cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
||||
cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
||||
cloud.google.com/go/storage v1.37.0/go.mod h1:i34TiT2IhiNDmcj65PqwCjcoUX7Z5pLzS8DEmoiFq1k=
|
||||
cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA=
|
||||
@@ -884,6 +902,7 @@ cloud.google.com/go/translate v1.9.2/go.mod h1:E3Tc6rUTsQkVrXW6avbUhKJSr7ZE3j7zN
|
||||
cloud.google.com/go/translate v1.9.3/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0=
|
||||
cloud.google.com/go/translate v1.10.0/go.mod h1:Kbq9RggWsbqZ9W5YpM94Q1Xv4dshw/gr/SHfsl5yCZ0=
|
||||
cloud.google.com/go/translate v1.10.1/go.mod h1:adGZcQNom/3ogU65N9UXHOnnSvjPwA/jKQUMnsYXOyk=
|
||||
cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs=
|
||||
cloud.google.com/go/translate v1.12.1 h1:Vws9BGpVcaOeI6HodyWdvysUzHUBFvk7ymHu1tzFvuM=
|
||||
cloud.google.com/go/translate v1.12.1/go.mod h1:5f4RvC7/hh76qSl6LYuqOJaKbIzEpR1Sj+CMA6gSgIk=
|
||||
cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU=
|
||||
@@ -1016,6 +1035,8 @@ github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeE
|
||||
github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.28.3 h1:SkFzPULX6nzgfNZd1YD1XTECivjTMrCtD09ZPKcVLFQ=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.28.3/go.mod h1:vzn73hp+3JwxtFU4RjPCQ7r6fP2pMKVwdi8E1/Tkua8=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0 h1:AG4D/hW39qa58+JHQIFOSnxyL46H6h2lrmGGk17dhFo=
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.30.0/go.mod h1:i9ZQAojcayW3RsdCb3YR+n+wC2h65eJsZCscZ1Z1wyo=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 h1:sR+/8Yb4slttB4vD+b9btVEnWgL3Q00OBTzVT8B9C0c=
|
||||
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
|
||||
github.com/CloudyKit/jet/v6 v6.2.0 h1:EpcZ6SR9n28BUGtNJSvlBqf90IpjeFr36Tizxhn/oME=
|
||||
@@ -1101,6 +1122,7 @@ github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEq
|
||||
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40 h1:q4dksr6ICHXqG5hm0ZW5IHyeEJXoIJSOZeBLmWPNeIQ=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40/go.mod h1:Q7yQnSMnLvcXlZ8RV+jwz/6y1rQTqbX6C82SndT52Zs=
|
||||
github.com/apache/arrow/go/v10 v10.0.1 h1:n9dERvixoC/1JjDmBcs9FPaEryoANa2sCgVFo6ez9cI=
|
||||
@@ -1302,8 +1324,10 @@ github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
|
||||
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||
github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b h1:ZHiD4/yE4idlbqvAO6iYCOYRzOMRpxkW+FKasRA3tsQ=
|
||||
github.com/efficientgo/tools/core v0.0.0-20220225185207-fe763185946b/go.mod h1:OmVcnJopJL8d3X3sSXTiypGoUSgFq1aDGmlrdi9dn/M=
|
||||
github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM=
|
||||
github.com/elastic/go-sysinfo v1.11.2 h1:mcm4OSYVMyws6+n2HIVMGkln5HOpo5Ie1ZmbbNn0jg4=
|
||||
github.com/elastic/go-sysinfo v1.11.2/go.mod h1:GKqR8bbMK/1ITnez9NIsIfXQr25aLhRJa7AfT8HpBFQ=
|
||||
github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
|
||||
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/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw=
|
||||
@@ -1432,6 +1456,7 @@ github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMc
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/pprof v0.0.0-20240416155748-26353dc0451f/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
||||
@@ -1443,9 +1468,13 @@ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.4/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.3/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||
github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc=
|
||||
github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4=
|
||||
github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
|
||||
github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
|
||||
github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk=
|
||||
github.com/googleapis/gnostic v0.3.0 h1:CcQijm0XKekKjP/YCz28LXVSpgguuB+nCxaSjCe09y0=
|
||||
github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 h1:zC34cGQu69FG7qzJ3WiKW244WfhDC3xxYMeNOX2gtUQ=
|
||||
@@ -1472,6 +1501,8 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
|
||||
github.com/hamba/avro/v2 v2.27.0 h1:IAM4lQ0VzUIKBuo4qlAiLKfqALSrFC+zi1iseTtbBKU=
|
||||
@@ -1542,6 +1573,7 @@ github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInw
|
||||
github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
|
||||
github.com/jedib0t/go-pretty/v6 v6.2.4 h1:wdaj2KHD2W+mz8JgJ/Q6L/T5dB7kyqEFI16eLq7GEmk=
|
||||
github.com/jedib0t/go-pretty/v6 v6.2.4/go.mod h1:+nE9fyyHGil+PuISTCrp7avEdo6bqoMwqZnuiK2r2a0=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.4.1-0.20181029123624-5de817a9aa20/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jhump/gopoet v0.1.0 h1:gYjOPnzHd2nzB37xYQZxj4EIQNpBrBskRqQQ3q4ZgSg=
|
||||
github.com/jhump/goprotoc v0.5.0 h1:Y1UgUX+txUznfqcGdDef8ZOVlyQvnV0pKWZH08RmZuo=
|
||||
@@ -1583,7 +1615,9 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46 h1:veS9QfglfvqAw2e+eeNT/SbGySq8ajECXJ9e4fPoLhY=
|
||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid v1.3.1 h1:5JNjFYYQrZeKRJ0734q51WCEEn2huer72Dc7K+R/b6s=
|
||||
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
|
||||
github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
@@ -1635,6 +1669,8 @@ github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04
|
||||
github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM=
|
||||
github.com/mfridman/xflag v0.0.0-20240825232106-efb77353e578 h1:CRrqlUmLebb/QjzRDWE0E66+YyN/v95+w6WyH9ju8/Y=
|
||||
github.com/mfridman/xflag v0.0.0-20240825232106-efb77353e578/go.mod h1:/483ywM5ZO5SuMVjrIGquYNE5CzLrj5Ux/LxWWnjRaE=
|
||||
github.com/mfridman/xflag v0.1.0 h1:TWZrZwG1QklFX5S4j1vxfF1sZbZeZSGofMwPMLAF29M=
|
||||
github.com/mfridman/xflag v0.1.0/go.mod h1:/483ywM5ZO5SuMVjrIGquYNE5CzLrj5Ux/LxWWnjRaE=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg=
|
||||
github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
@@ -1772,6 +1808,7 @@ github.com/open-telemetry/opentelemetry-collector-contrib/receiver/zipkinreceive
|
||||
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
|
||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/openfga/api/proto v0.0.0-20240905181937-3583905f61a6/go.mod h1:gil5LBD8tSdFQbUkCQdnXsoeU9kDJdJgbGdHkgJfcd0=
|
||||
github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
|
||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
@@ -1785,11 +1822,13 @@ github.com/parquet-go/parquet-go v0.23.0 h1:dyEU5oiHCtbASyItMCD2tXtT2nPmoPbKpqf0
|
||||
github.com/parquet-go/parquet-go v0.23.0/go.mod h1:MnwbUcFHU6uBYMymKAlPPAw9yh3kE1wWl6Gl1uLdkNk=
|
||||
github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
|
||||
github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
|
||||
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
|
||||
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30 h1:BHT1/DKsYDGkUgQ2jmMaozVcdk+sVfz0+1ZJq4zkWgw=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/performancecopilot/speed/v4 v4.0.0 h1:VxEDCmdkfbQYDlcr/GC9YoN9PQ6p8ulk9xVsepYy9ZY=
|
||||
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
@@ -1812,10 +1851,13 @@ github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8
|
||||
github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_golang v1.20.4/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
|
||||
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/common/assets v0.2.0 h1:0P5OrzoHrYBOSM1OigWL3mY8ZvV2N4zIE/5AahrSrfM=
|
||||
github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/prometheus v0.52.0 h1:f7kHJgr7+zShpWdTCeKqbCWR7nKTScgLYQwRux9h1V0=
|
||||
github.com/prometheus/prometheus v0.52.0/go.mod h1:3z74cVsmVH0iXOR5QBjB7Pa6A0KJeEAK5A6UsmAFb1g=
|
||||
github.com/prometheus/statsd_exporter v0.26.0 h1:SQl3M6suC6NWQYEzOvIv+EF6dAMYEqIuZy+o4H9F5Ig=
|
||||
@@ -1859,8 +1901,10 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc=
|
||||
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/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
@@ -1880,6 +1924,8 @@ github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvF
|
||||
github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM=
|
||||
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
|
||||
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
@@ -1919,7 +1965,9 @@ github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX
|
||||
github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8=
|
||||
github.com/xanzy/go-gitlab v0.15.0 h1:rWtwKTgEnXyNUGrOArN7yyc3THRkpYcKXIXia9abywQ=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
|
||||
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
|
||||
@@ -1936,8 +1984,12 @@ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow=
|
||||
github.com/ydb-platform/ydb-go-genproto v0.0.0-20240528144234-5d5a685e41f7 h1:nL8XwD6fSst7xFUirkaWJmE7kM0CdWRYgu6+YQer1d4=
|
||||
github.com/ydb-platform/ydb-go-genproto v0.0.0-20240528144234-5d5a685e41f7/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I=
|
||||
github.com/ydb-platform/ydb-go-genproto v0.0.0-20241112172322-ea1f63298f77 h1:LY6cI8cP4B9rrpTleZk95+08kl2gF4rixG7+V/dwL6Q=
|
||||
github.com/ydb-platform/ydb-go-genproto v0.0.0-20241112172322-ea1f63298f77/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I=
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.80.2 h1:qmZGJQCNx09/r0HDIT2cDDogiOvWikELy13ubM2CFS8=
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.80.2/go.mod h1:IHwuXyolaAmGK2Dp7+dlhsnXphG1pwCoaP/OITT3+tU=
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.95.3 h1:pgsQPKSFfRFy3JSZMUReCF4CSEwgxA+a5GymvtyRJO0=
|
||||
github.com/ydb-platform/ydb-go-sdk/v3 v3.95.3/go.mod h1:WiezFS4YCi2vHqbYGQkeu/2MDBYFLix6dIs/pd87Yck=
|
||||
github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA=
|
||||
github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0=
|
||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
||||
@@ -1958,6 +2010,7 @@ go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsX
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg=
|
||||
go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M=
|
||||
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
|
||||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.opentelemetry.io/collector v0.102.1 h1:M/ciCcReQsSDYG9bJ2Qwqk7pQILDJ2bM/l0MdeCAvJE=
|
||||
go.opentelemetry.io/collector v0.102.1/go.mod h1:yF1lDRgL/Eksb4/LUnkMjvLvHHpi6wqBVlzp+dACnPM=
|
||||
@@ -2039,10 +2092,12 @@ go.opentelemetry.io/contrib/exporters/autoexport v0.53.0/go.mod h1:lyQF6xQ4iDnMg
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.27.0 h1:IjgxbomVrV9za6bRi8fWCNXENs0co37SZedQilP2hm0=
|
||||
go.opentelemetry.io/contrib/propagators/b3 v1.27.0/go.mod h1:Dv9obQz25lCisDvvs4dy28UPh974CxkahRDUPsY7y9E=
|
||||
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
|
||||
@@ -2050,6 +2105,9 @@ go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZV
|
||||
go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg=
|
||||
go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
|
||||
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel/bridge/opencensus v1.27.0 h1:ao9aGGHd+G4YfjBpGs6vbkvt5hoC67STlJA9fCnOAcs=
|
||||
go.opentelemetry.io/otel/bridge/opencensus v1.27.0/go.mod h1:uRvWtAAXzyVOST0WMPX5JHGBaAvBws+2F8PcC5gMnTk=
|
||||
go.opentelemetry.io/otel/bridge/opentracing v1.26.0 h1:Q/dHj0DOhfLMAs5u5ucAbC7gy66x9xxsZRLpHCJ4XhI=
|
||||
@@ -2060,6 +2118,7 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0 h1:aLm
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.28.0/go.mod h1:TC1pyCt6G9Sjb4bQpShH+P5R53pO6ZuGnHuuln9xMeE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.22.0/go.mod h1:hYwym2nDEeZfG/motx0p7L7J1N1vyzIThemQsb4g2qY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0/go.mod h1:e7ciERRhZaOZXVjx5MiL8TK5+Xv7G5Gv5PA2ZDEJdL8=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.50.0 h1:2Ewsda6hejmbhGFyUvWZjUThC98Cf8Zy6g0zkIimOng=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.50.0/go.mod h1:pMm5PkUo5YwbLiuEf7t2xg4wbP0/eSJrMxIMxKosynY=
|
||||
@@ -2074,13 +2133,21 @@ go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xC
|
||||
go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s=
|
||||
go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
|
||||
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||
go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw=
|
||||
go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
|
||||
go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo=
|
||||
go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I=
|
||||
go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
|
||||
go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
@@ -2106,13 +2173,21 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y
|
||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
|
||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/exp v0.0.0-20220328175248-053ad81199eb/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
||||
golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e h1:qyrTQ++p1afMkO4DPEeLGq/3oTsdlvdH4vqZUBWzUKM=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
|
||||
@@ -2128,6 +2203,9 @@ golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
@@ -2144,6 +2222,12 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
|
||||
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
|
||||
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
|
||||
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
|
||||
@@ -2152,8 +2236,12 @@ golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCA
|
||||
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||
golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -2170,6 +2258,12 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
@@ -2184,9 +2278,14 @@ golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
@@ -2198,6 +2297,7 @@ golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
||||
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
|
||||
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
|
||||
golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
@@ -2205,6 +2305,10 @@ golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0
|
||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
|
||||
golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=
|
||||
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc=
|
||||
@@ -2215,6 +2319,7 @@ google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWL
|
||||
google.golang.org/api v0.139.0/go.mod h1:CVagp6Eekz9CjGZ718Z+sloknzkDJE7Vc1Ckj9+viBk=
|
||||
google.golang.org/api v0.149.0/go.mod h1:Mwn1B7JTXrzXtnvmzQE2BD6bYZQ8DShKZDZbeN9I7qI=
|
||||
google.golang.org/api v0.150.0/go.mod h1:ccy+MJ6nrYFgE3WgRx/AMXOxOmU8Q4hSa+jjibzhxcg=
|
||||
google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
|
||||
google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk=
|
||||
google.golang.org/api v0.157.0/go.mod h1:+z4v4ufbZ1WEpld6yMGHyggs+PmAHiaLNj5ytP3N01g=
|
||||
google.golang.org/api v0.160.0/go.mod h1:0mu0TpK33qnydLvWqbImq2b1eQ5FHRSDCBzAxX9ZHyw=
|
||||
@@ -2222,6 +2327,11 @@ google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYl
|
||||
google.golang.org/api v0.164.0/go.mod h1:2OatzO7ZDQsoS7IFf3rvsE17/TldiU3F/zxFHeqUB5o=
|
||||
google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg=
|
||||
google.golang.org/api v0.174.0/go.mod h1:aC7tB6j0HR1Nl0ni5ghpx6iLasmAX78Zkh/wgxAAjLg=
|
||||
google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw=
|
||||
google.golang.org/api v0.187.0/go.mod h1:KIHlTc4x7N7gKKuVsdmfBXN13yEEWXWFURWY6SBp2gk=
|
||||
google.golang.org/api v0.196.0/go.mod h1:g9IL21uGkYgvQ5BZg6BAtoGJQIm8r6EgaAbpNey5wBE=
|
||||
google.golang.org/api v0.197.0/go.mod h1:AuOuo20GoQ331nq7DquGHlU6d+2wN2fZ8O0ta60nRNw=
|
||||
google.golang.org/api v0.211.0/go.mod h1:XOloB4MXFH4UTlQSGuNUxw0UT74qdENK8d6JNsXKLi0=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
@@ -2251,6 +2361,8 @@ google.golang.org/genproto v0.0.0-20240125205218-1f4bbc51befe/go.mod h1:cc8bqMqt
|
||||
google.golang.org/genproto v0.0.0-20240205150955-31a09d347014/go.mod h1:xEgQu1e4stdSSsxPDK8Azkrk/ECl5HvdPf6nbZrTS5M=
|
||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
|
||||
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
|
||||
google.golang.org/genproto v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:s7iA721uChleev562UJO2OYB0PPT9CMFjV+Ce7VJH5M=
|
||||
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=
|
||||
@@ -2277,6 +2389,14 @@ google.golang.org/genproto/googleapis/api v0.0.0-20240213162025-012b6fc9bca9/go.
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:E5//3O5ZIG2l71Xnt+P/CYUY8Bxs8E7WMoZ9tlcMbAY=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20231030173426-d783a09b4405/go.mod h1:GRUCuLdzVqZte8+Dl/D4N25yLzcGqqWaYkeVOwulFqw=
|
||||
google.golang.org/genproto/googleapis/bytestream v0.0.0-20231212172506-995d672761c0/go.mod h1:guYXGPwC6jwxgWKW5Y405fKWOFNwlvUlUnzyp9i0uqo=
|
||||
@@ -2315,9 +2435,20 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20240228201840-1f18d85a4ec2/go.
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240304161311-37d4d3c04a78/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240311132316-a219d84964c2/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415141817-7cd4c1c1f9ec/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240624140628-dc46fd24d27d/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241206012308-a4fef0638583/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241219192143-6b3ec007d9bb/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241223144023-3abc09e42ca8/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA=
|
||||
google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
|
||||
google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
@@ -2333,8 +2464,19 @@ google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJai
|
||||
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0=
|
||||
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||
google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
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=
|
||||
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=
|
||||
@@ -2349,10 +2491,13 @@ gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzE
|
||||
gopkg.in/telebot.v3 v3.2.1 h1:3I4LohaAyJBiivGmkfB+CiVu7QFOWkuZ4+KHgO/G3rs=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||
gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
|
||||
honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
|
||||
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
|
||||
@@ -2406,6 +2551,7 @@ modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0=
|
||||
modernc.org/sqlite v1.21.2/go.mod h1:cxbLkB5WS32DnQqeH4h4o1B0eMr8W/y8/RGuxQ3JsC0=
|
||||
modernc.org/sqlite v1.34.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao=
|
||||
modernc.org/tcl v1.13.2/go.mod h1:7CLiGIPo1M8Rv1Mitpv5akc2+8fxUd2y2UzC/MfMzy0=
|
||||
modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws=
|
||||
|
||||
+4
-5
@@ -291,10 +291,10 @@
|
||||
"@opentelemetry/exporter-collector": "0.25.0",
|
||||
"@opentelemetry/semantic-conventions": "1.28.0",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@react-aria/dialog": "3.5.20",
|
||||
"@react-aria/focus": "3.19.0",
|
||||
"@react-aria/overlays": "3.24.0",
|
||||
"@react-aria/utils": "3.26.0",
|
||||
"@react-aria/dialog": "3.5.21",
|
||||
"@react-aria/focus": "3.19.1",
|
||||
"@react-aria/overlays": "3.25.0",
|
||||
"@react-aria/utils": "3.27.0",
|
||||
"@react-awesome-query-builder/ui": "6.6.4",
|
||||
"@reduxjs/toolkit": "2.5.0",
|
||||
"@visx/event": "3.12.0",
|
||||
@@ -359,7 +359,6 @@
|
||||
"pluralize": "^8.0.0",
|
||||
"prismjs": "1.29.0",
|
||||
"rc-slider": "11.1.8",
|
||||
"rc-time-picker": "3.7.3",
|
||||
"rc-tree": "5.13.0",
|
||||
"re-resizable": "6.10.3",
|
||||
"react": "18.2.0",
|
||||
|
||||
@@ -42,7 +42,10 @@ describe('ensureColumns transformer', () => {
|
||||
options: {},
|
||||
};
|
||||
|
||||
const data = [seriesA, seriesBC];
|
||||
const data = [
|
||||
{ refId: 'A', ...seriesA },
|
||||
{ refId: 'B', ...seriesBC },
|
||||
];
|
||||
|
||||
await expect(transformDataFrame([cfg], data)).toEmitValuesWith((received) => {
|
||||
const filtered = received[0];
|
||||
@@ -109,6 +112,7 @@ describe('ensureColumns transformer', () => {
|
||||
},
|
||||
],
|
||||
"length": 2,
|
||||
"refId": "joinByField-A-B",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
@@ -592,5 +592,6 @@ export function histogramFieldsToFrame(info: HistogramFields, theme?: GrafanaThe
|
||||
type: DataFrameType.Histogram,
|
||||
},
|
||||
fields: [info.xMin, info.xMax, ...info.counts],
|
||||
refId: `${DataTransformerID.histogram}`,
|
||||
};
|
||||
}
|
||||
@@ -42,6 +42,7 @@ export const joinByFieldTransformer: SynchronousDataTransformerInfo<JoinByFieldO
|
||||
}
|
||||
const joined = joinDataFrames({ frames: data, joinBy, mode: options.mode });
|
||||
if (joined) {
|
||||
joined.refId = `${DataTransformerID.joinByField}-${data.map((frame) => frame.refId).join('-')}`;
|
||||
return [joined];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,10 @@ export const mergeTransformer: DataTransformerInfo<MergeTransformerOptions> = {
|
||||
const fieldNames = new Set<string>();
|
||||
const fieldIndexByName: Record<string, Record<number, number>> = {};
|
||||
const fieldNamesForKey: string[] = [];
|
||||
const dataFrame = new MutableDataFrame();
|
||||
const dataFrame = new MutableDataFrame({
|
||||
refId: `${DataTransformerID.merge}-${data.map((frame) => frame.refId).join('-')}`,
|
||||
fields: [],
|
||||
});
|
||||
|
||||
for (let frameIndex = 0; frameIndex < data.length; frameIndex++) {
|
||||
const frame = data[frameIndex];
|
||||
|
||||
@@ -56,7 +56,9 @@ export const reduceTransformer: DataTransformerInfo<ReduceTransformerOptions> =
|
||||
|
||||
// Add a row for each series
|
||||
const res = reduceSeriesToRows(data, matcher, options.reducers, options.labelsToFields);
|
||||
return res ? [res] : [];
|
||||
return res
|
||||
? [{ ...res, refId: `${DataTransformerID.reduce}-${data.map((frame) => frame.refId).join('-')}` }]
|
||||
: [];
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
@@ -37,7 +37,10 @@ export const seriesToRowsTransformer: DataTransformerInfo<SeriesToRowsTransforme
|
||||
|
||||
const timeFieldByIndex: Record<number, number> = {};
|
||||
const targetFields = new Set<string>();
|
||||
const dataFrame = new MutableDataFrame();
|
||||
const dataFrame = new MutableDataFrame({
|
||||
refId: `${DataTransformerID.seriesToRows}-${data.map((frame) => frame.refId).join('-')}`,
|
||||
fields: [],
|
||||
});
|
||||
const metricField: Field = {
|
||||
name: TIME_SERIES_METRIC_FIELD_NAME,
|
||||
values: [],
|
||||
|
||||
@@ -80,6 +80,7 @@ function transposeDataFrame(options: TransposeTransformerOptions, data: DataFram
|
||||
...frame,
|
||||
fields: newFields,
|
||||
length: Math.max(...newFields.map((field) => field.values.length)),
|
||||
refId: `${DataTransformerID.transpose}-${frame.refId}`,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -112,4 +112,24 @@ describe('addLabelToQuery()', () => {
|
||||
it('should not add ad-hoc filter bool operator', () => {
|
||||
expect(addLabelToQuery('ALERTS < bool 1', 'bar', 'baz')).toBe('ALERTS{bar="baz"} < bool 1');
|
||||
});
|
||||
|
||||
it('should add a utf8 label', () => {
|
||||
expect(addLabelToQuery('{"metric.name"}', 'cenk.erdem', 'muhabbet')).toBe(
|
||||
'{"metric.name", "cenk.erdem"="muhabbet"}'
|
||||
);
|
||||
|
||||
expect(addLabelToQuery('metric{label="val"}', 'cenk.erdem', 'muhabbet')).toBe(
|
||||
'metric{label="val", "cenk.erdem"="muhabbet"}'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not add a utf8 label when it is already applied', () => {
|
||||
expect(addLabelToQuery('{"metric.name", "cenk.erdem"="muhabbet"}', 'cenk.erdem', 'muhabbet')).toBe(
|
||||
'{"metric.name", "cenk.erdem"="muhabbet"}'
|
||||
);
|
||||
|
||||
expect(addLabelToQuery('metric{label="val", "cenk.erdem"="muhabbet"}', 'cenk.erdem', 'muhabbet')).toBe(
|
||||
'metric{label="val", "cenk.erdem"="muhabbet"}'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -54,6 +54,49 @@ describe('buildSelector()', () => {
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('foo{bar="baz"}');
|
||||
});
|
||||
|
||||
describe('utf8 support', () => {
|
||||
it('metric selector with utf8 metric', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'utf8.metric', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('{"utf8.metric"}');
|
||||
});
|
||||
|
||||
it('metric selector with utf8 labels', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'foo', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('foo{"utf8.label"="baz"}');
|
||||
});
|
||||
|
||||
it('metric selector with utf8 labels and metrics', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'utf8.metric', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('{"utf8.metric","utf8.label"="baz"}');
|
||||
});
|
||||
|
||||
it('metric selector with utf8 metric and with utf8/non-utf8 labels', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'utf8.metric', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'uuu', selected: true }] },
|
||||
{ name: 'bar', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('{"utf8.metric","utf8.label"="uuu",bar="baz"}');
|
||||
});
|
||||
|
||||
it('metric selector with non-utf8 metric with utf8/non-utf8 labels', () => {
|
||||
const labels: SelectableLabel[] = [
|
||||
{ name: '__name__', selected: true, values: [{ name: 'foo', selected: true }] },
|
||||
{ name: 'utf8.label', selected: true, values: [{ name: 'uuu', selected: true }] },
|
||||
{ name: 'bar', selected: true, values: [{ name: 'baz', selected: true }] },
|
||||
];
|
||||
expect(buildSelector(labels)).toEqual('foo{"utf8.label"="uuu",bar="baz"}');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('facetLabels()', () => {
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
|
||||
import PromQlLanguageProvider from '../language_provider';
|
||||
import { escapeLabelValueInExactSelector, escapeLabelValueInRegexSelector } from '../language_utils';
|
||||
import { isValidLegacyName, utf8Support } from '../utf8_support';
|
||||
|
||||
// Hard limit on labels to render
|
||||
const EMPTY_SELECTOR = '{}';
|
||||
@@ -68,22 +69,38 @@ export interface SelectableLabel {
|
||||
|
||||
export function buildSelector(labels: SelectableLabel[]): string {
|
||||
let singleMetric = '';
|
||||
const selectedLabels = [];
|
||||
const selectedLabels: string[] = [];
|
||||
for (const label of labels) {
|
||||
if ((label.name === METRIC_LABEL || label.selected) && label.values && label.values.length > 0) {
|
||||
const selectedValues = label.values.filter((value) => value.selected).map((value) => value.name);
|
||||
if (selectedValues.length > 1) {
|
||||
selectedLabels.push(`${label.name}=~"${selectedValues.map(escapeLabelValueInRegexSelector).join('|')}"`);
|
||||
selectedLabels.push(
|
||||
`${utf8Support(label.name)}=~"${selectedValues.map(escapeLabelValueInRegexSelector).join('|')}"`
|
||||
);
|
||||
} else if (selectedValues.length === 1) {
|
||||
if (label.name === METRIC_LABEL) {
|
||||
singleMetric = selectedValues[0];
|
||||
} else {
|
||||
selectedLabels.push(`${label.name}="${escapeLabelValueInExactSelector(selectedValues[0])}"`);
|
||||
selectedLabels.push(`${utf8Support(label.name)}="${escapeLabelValueInExactSelector(selectedValues[0])}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [singleMetric, '{', selectedLabels.join(','), '}'].join('');
|
||||
|
||||
const selectorParts: string[] = [];
|
||||
const isLegacyName = singleMetric === '' || isValidLegacyName(singleMetric);
|
||||
|
||||
if (isLegacyName) {
|
||||
selectorParts.push(singleMetric, '{');
|
||||
} else {
|
||||
selectorParts.push('{', `"${singleMetric}"`);
|
||||
if (selectedLabels.length > 0) {
|
||||
selectorParts.push(',');
|
||||
}
|
||||
}
|
||||
|
||||
selectorParts.push(selectedLabels.join(','), '}');
|
||||
return selectorParts.join('');
|
||||
}
|
||||
|
||||
export function facetLabels(
|
||||
|
||||
+37
-7
@@ -1,11 +1,13 @@
|
||||
// Core grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/components/monaco-query-field/monaco-completion-provider/completions.ts
|
||||
import UFuzzy from '@leeoniya/ufuzzy';
|
||||
import { languages } from 'monaco-editor';
|
||||
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import { prometheusRegularEscape } from '../../../datasource';
|
||||
import { escapeLabelValueInExactSelector } from '../../../language_utils';
|
||||
import { FUNCTIONS } from '../../../promql';
|
||||
import { isValidLegacyName } from '../../../utf8_support';
|
||||
|
||||
import { DataProvider } from './data_provider';
|
||||
import type { Label, Situation } from './situation';
|
||||
@@ -14,10 +16,16 @@ import { NeverCaseError } from './util';
|
||||
|
||||
export type CompletionType = 'HISTORY' | 'FUNCTION' | 'METRIC_NAME' | 'DURATION' | 'LABEL_NAME' | 'LABEL_VALUE';
|
||||
|
||||
// We cannot use languages.CompletionItemInsertTextRule.InsertAsSnippet because grafana-prometheus package isn't compatible
|
||||
// It should first change the moduleResolution to bundler for TS to correctly resolve the types
|
||||
// https://github.com/grafana/grafana/pull/96450
|
||||
const InsertAsSnippet = 4;
|
||||
|
||||
type Completion = {
|
||||
type: CompletionType;
|
||||
label: string;
|
||||
insertText: string;
|
||||
insertTextRules?: languages.CompletionItemInsertTextRule;
|
||||
detail?: string;
|
||||
documentation?: string;
|
||||
triggerOnInsert?: boolean;
|
||||
@@ -29,6 +37,11 @@ const metricNamesSearch = {
|
||||
singleError: new UFuzzy({ intraMode: 1 }),
|
||||
};
|
||||
|
||||
// Snippet Marker is telling monaco where to show the cursor and maybe a help text
|
||||
// With help text example: ${1:labelName}
|
||||
// labelName will be shown as selected. So user would know what to type next
|
||||
const snippetMarker = '${1:}';
|
||||
|
||||
interface MetricFilterOptions {
|
||||
metricNames: string[];
|
||||
inputText: string;
|
||||
@@ -74,9 +87,16 @@ function getAllMetricNamesCompletions(dataProvider: DataProvider): Completion[]
|
||||
return dataProvider.metricNamesToMetrics(metricNames).map((metric) => ({
|
||||
type: 'METRIC_NAME',
|
||||
label: metric.name,
|
||||
insertText: metric.name,
|
||||
detail: `${metric.name} : ${metric.type}`,
|
||||
documentation: metric.help,
|
||||
...(metric.isUtf8
|
||||
? {
|
||||
insertText: `{"${metric.name}"${snippetMarker}}`,
|
||||
insertTextRules: InsertAsSnippet,
|
||||
}
|
||||
: {
|
||||
insertText: metric.name,
|
||||
}),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -159,12 +179,22 @@ async function getLabelNamesForCompletions(
|
||||
dataProvider: DataProvider
|
||||
): Promise<Completion[]> {
|
||||
const labelNames = await getLabelNames(metric, otherLabels, dataProvider);
|
||||
return labelNames.map((text) => ({
|
||||
type: 'LABEL_NAME',
|
||||
label: text,
|
||||
insertText: `${text}${suffix}`,
|
||||
triggerOnInsert,
|
||||
}));
|
||||
return labelNames.map((text) => {
|
||||
const isUtf8 = !isValidLegacyName(text);
|
||||
return {
|
||||
type: 'LABEL_NAME',
|
||||
label: text,
|
||||
...(isUtf8
|
||||
? {
|
||||
insertText: `"${text}"${suffix}`,
|
||||
insertTextRules: InsertAsSnippet,
|
||||
}
|
||||
: {
|
||||
insertText: `${text}${suffix}`,
|
||||
}),
|
||||
triggerOnInsert,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async function getLabelNamesForSelectorCompletions(
|
||||
|
||||
+3
@@ -3,6 +3,7 @@ import type { Monaco } from '@grafana/ui'; // used in TSDoc `@link` below
|
||||
|
||||
import PromQlLanguageProvider from '../../../language_provider';
|
||||
import { PromQuery } from '../../../types';
|
||||
import { isValidLegacyName } from '../../../utf8_support';
|
||||
|
||||
export const CODE_MODE_SUGGESTIONS_INCOMPLETE_EVENT = 'codeModeSuggestionsIncomplete';
|
||||
|
||||
@@ -26,6 +27,7 @@ interface Metric {
|
||||
name: string;
|
||||
help: string;
|
||||
type: string;
|
||||
isUtf8?: boolean;
|
||||
}
|
||||
|
||||
export interface DataProviderParams {
|
||||
@@ -78,6 +80,7 @@ export class DataProvider {
|
||||
name: m,
|
||||
help: metaItem?.help ?? '',
|
||||
type: metaItem?.type ?? '',
|
||||
isUtf8: !isValidLegacyName(m),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
+1
@@ -95,6 +95,7 @@ export function getCompletionProvider(
|
||||
kind: getMonacoCompletionItemKind(item.type, monaco),
|
||||
label: item.label,
|
||||
insertText: item.insertText,
|
||||
insertTextRules: item.insertTextRules,
|
||||
detail: item.detail,
|
||||
documentation: item.documentation,
|
||||
sortText: index.toString().padStart(maxIndexDigits, '0'), // to force the order we have
|
||||
|
||||
+125
@@ -56,6 +56,7 @@ describe('situation', () => {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
otherLabels: [],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
|
||||
assertSituation('sum(something) by (^)', {
|
||||
@@ -79,34 +80,157 @@ describe('situation', () => {
|
||||
{ name: 'three', value: 'val3', op: '=~' },
|
||||
{ name: 'four', value: 'val4', op: '!~' },
|
||||
],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
|
||||
assertSituation('{^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
|
||||
assertSituation('{one="val1",^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: 'val1', op: '=' }],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
|
||||
// single-quoted label-values with escape
|
||||
assertSituation("{one='val\\'1',^}", {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: "val'1", op: '=' }],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
|
||||
// double-quoted label-values with escape
|
||||
assertSituation('{one="val\\"1",^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: 'val"1', op: '=' }],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
|
||||
// backticked label-values with escape (the escape should not be interpreted)
|
||||
assertSituation('{one=`val\\"1`,^}', {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels: [{ name: 'one', value: 'val\\"1', op: '=' }],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
});
|
||||
|
||||
describe('utf-8 metric name support', () => {
|
||||
it('with utf8 metric name no label and no comma', () => {
|
||||
assertSituation(`{"metric.name"^}`, null);
|
||||
});
|
||||
|
||||
it('with utf8 metric name no label', () => {
|
||||
assertSituation(`{"metric.name", ^}`, {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName: 'metric.name',
|
||||
otherLabels: [],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('with utf8 metric name requesting utf8 labels in quotes', () => {
|
||||
assertSituation(`{"metric.name", "^"}`, {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName: 'metric.name',
|
||||
otherLabels: [],
|
||||
betweenQuotes: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('with utf8 metric name with a legacy label', () => {
|
||||
assertSituation(`{"metric.name", label1="val", ^}`, {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName: 'metric.name',
|
||||
otherLabels: [{ name: 'label1', value: 'val', op: '=' }],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('with utf8 metric name with a legacy label and no value', () => {
|
||||
assertSituation(`{"metric.name", label1="^"}`, {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'metric.name',
|
||||
labelName: 'label1',
|
||||
betweenQuotes: true,
|
||||
otherLabels: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('with utf8 metric name with a utf8 label and no value', () => {
|
||||
assertSituation(`{"metric.name", "utf8.label"="^"}`, {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'metric.name',
|
||||
labelName: '"utf8.label"',
|
||||
betweenQuotes: true,
|
||||
otherLabels: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('with utf8 metric name with a legacy label and utf8 label', () => {
|
||||
assertSituation(`{"metric.name", label1="val", "utf8.label"="^"}`, {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'metric.name',
|
||||
labelName: `"utf8.label"`,
|
||||
betweenQuotes: true,
|
||||
otherLabels: [{ name: 'label1', value: 'val', op: '=' }],
|
||||
});
|
||||
});
|
||||
|
||||
it('with utf8 metric name with a utf8 label and legacy label', () => {
|
||||
assertSituation(`{"metric.name", "utf8.label"="val", label1="^"}`, {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'metric.name',
|
||||
labelName: `label1`,
|
||||
betweenQuotes: true,
|
||||
otherLabels: [{ name: '"utf8.label"', value: 'val', op: '=' }],
|
||||
});
|
||||
});
|
||||
|
||||
it('with utf8 metric name with grouping', () => {
|
||||
assertSituation(`sum by (^)(rate({"metric.name", label1="val"}[1m]))`, {
|
||||
type: 'IN_GROUPING',
|
||||
metricName: 'metric.name',
|
||||
otherLabels: [],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('utf-8 label support', () => {
|
||||
assertSituation(`metric{"label": "^"}`, null);
|
||||
|
||||
assertSituation(`metric{"label with space": "^"}`, null);
|
||||
|
||||
assertSituation(`metric{"label_🤖": "^"}`, null);
|
||||
|
||||
assertSituation(`metric{"Spaß": "^"}`, null);
|
||||
|
||||
assertSituation(`{"metric", "Spaß": "^"}`, null);
|
||||
|
||||
assertSituation('something{"job"=^}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: '"job"',
|
||||
betweenQuotes: false,
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertSituation('something{"job📈"=^}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: '"job📈"',
|
||||
betweenQuotes: false,
|
||||
otherLabels: [],
|
||||
});
|
||||
|
||||
assertSituation('something{"job with space"=^,host="h1"}', {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName: 'something',
|
||||
labelName: '"job with space"',
|
||||
betweenQuotes: false,
|
||||
otherLabels: [{ name: 'host', value: 'h1', op: '=' }],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -194,6 +318,7 @@ describe('situation', () => {
|
||||
{ name: 'three', value: 'val3', op: '=~' },
|
||||
{ name: 'four', value: 'val4', op: '!~' },
|
||||
],
|
||||
betweenQuotes: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
+154
-46
@@ -18,6 +18,8 @@ import {
|
||||
NumberDurationLiteralInDurationContext,
|
||||
parser,
|
||||
PromQL,
|
||||
QuotedLabelMatcher,
|
||||
QuotedLabelName,
|
||||
StringLiteral,
|
||||
UnquotedLabelMatcher,
|
||||
VectorSelector,
|
||||
@@ -35,8 +37,10 @@ type NodeTypeId =
|
||||
| typeof GroupingLabels
|
||||
| typeof Identifier
|
||||
| typeof UnquotedLabelMatcher
|
||||
| typeof QuotedLabelMatcher
|
||||
| typeof LabelMatchers
|
||||
| typeof LabelName
|
||||
| typeof QuotedLabelName
|
||||
| typeof PromQL
|
||||
| typeof StringLiteral
|
||||
| typeof VectorSelector
|
||||
@@ -80,8 +84,10 @@ function walk(node: SyntaxNode, path: Path): SyntaxNode | null {
|
||||
return current;
|
||||
}
|
||||
|
||||
function getNodeText(node: SyntaxNode, text: string): string {
|
||||
return text.slice(node.from, node.to);
|
||||
function getNodeText(node: SyntaxNode, text: string, utf8?: boolean): string {
|
||||
const nodeFrom = utf8 ? node.from + 1 : node.from;
|
||||
const nodeTo = utf8 ? node.to - 1 : node.to;
|
||||
return text.slice(nodeFrom, nodeTo);
|
||||
}
|
||||
|
||||
function parsePromQLStringLiteral(text: string): string {
|
||||
@@ -140,6 +146,8 @@ export type Situation =
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME';
|
||||
metricName?: string;
|
||||
otherLabels: Label[];
|
||||
// utf8 labels must be in quotes
|
||||
betweenQuotes: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'IN_GROUPING';
|
||||
@@ -170,6 +178,10 @@ const RESOLVERS: Resolver[] = [
|
||||
path: [LabelMatchers, VectorSelector],
|
||||
fun: resolveLabelKeysWithEquals,
|
||||
},
|
||||
{
|
||||
path: [StringLiteral, QuotedLabelName, LabelMatchers, VectorSelector],
|
||||
fun: resolveUtf8LabelKeysWithEquals,
|
||||
},
|
||||
{
|
||||
path: [PromQL],
|
||||
fun: resolveTopLevel,
|
||||
@@ -182,6 +194,10 @@ const RESOLVERS: Resolver[] = [
|
||||
path: [StringLiteral, UnquotedLabelMatcher],
|
||||
fun: resolveLabelMatcher,
|
||||
},
|
||||
{
|
||||
path: [StringLiteral, QuotedLabelMatcher],
|
||||
fun: resolveQuotedLabelMatcher,
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_NAME, BinaryExpr, PromQL],
|
||||
fun: resolveTopLevel,
|
||||
@@ -190,6 +206,10 @@ const RESOLVERS: Resolver[] = [
|
||||
path: [ERROR_NODE_NAME, UnquotedLabelMatcher],
|
||||
fun: resolveLabelMatcher,
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_NAME, QuotedLabelMatcher],
|
||||
fun: resolveQuotedLabelMatcher,
|
||||
},
|
||||
{
|
||||
path: [ERROR_NODE_NAME, NumberDurationLiteralInDurationContext, MatrixSelector],
|
||||
fun: resolveDurations,
|
||||
@@ -217,11 +237,13 @@ function getLabelOp(opNode: SyntaxNode): LabelOperator | null {
|
||||
}
|
||||
|
||||
function getLabel(labelMatcherNode: SyntaxNode, text: string): Label | null {
|
||||
if (labelMatcherNode.type.id !== UnquotedLabelMatcher) {
|
||||
const allowedMatchers = new Set([UnquotedLabelMatcher, QuotedLabelMatcher]);
|
||||
if (!allowedMatchers.has(labelMatcherNode.type.id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const nameNode = walk(labelMatcherNode, [['firstChild', LabelName]]);
|
||||
const nameNode =
|
||||
walk(labelMatcherNode, [['firstChild', LabelName]]) ?? walk(labelMatcherNode, [['firstChild', QuotedLabelName]]);
|
||||
|
||||
if (nameNode === null) {
|
||||
return null;
|
||||
@@ -254,8 +276,17 @@ function getLabels(labelMatchersNode: SyntaxNode, text: string): Label[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
const labelNodes = labelMatchersNode.getChildren(UnquotedLabelMatcher);
|
||||
return labelNodes.map((ln) => getLabel(ln, text)).filter(notEmpty);
|
||||
const matchers = [UnquotedLabelMatcher, QuotedLabelMatcher];
|
||||
|
||||
return matchers.reduce<Label[]>((acc, matcher) => {
|
||||
labelMatchersNode.getChildren(matcher).forEach((ln) => {
|
||||
const label = getLabel(ln, text);
|
||||
if (notEmpty(label)) {
|
||||
acc.push(label);
|
||||
}
|
||||
});
|
||||
return acc;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function getNodeChildren(node: SyntaxNode): SyntaxNode[] {
|
||||
@@ -299,12 +330,20 @@ function resolveLabelsForGrouping(node: SyntaxNode, text: string, pos: number):
|
||||
return null;
|
||||
}
|
||||
|
||||
const metricIdNode = getNodeInSubtree(bodyNode, Identifier);
|
||||
if (metricIdNode === null) {
|
||||
const metricIdNode = getNodeInSubtree(bodyNode, Identifier) ?? getNodeInSubtree(bodyNode, StringLiteral);
|
||||
|
||||
if (!metricIdNode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const metricName = getNodeText(metricIdNode, text);
|
||||
// Let's check whether it's a utf8 metric.
|
||||
// A utf8 metric must be a StringLiteral and its parent must be a QuotedLabelName
|
||||
if (metricIdNode.type.id === StringLiteral && metricIdNode.parent?.type.id !== QuotedLabelName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const metricName = getNodeText(metricIdNode, text, metricIdNode.type.id === StringLiteral);
|
||||
|
||||
return {
|
||||
type: 'IN_GROUPING',
|
||||
metricName,
|
||||
@@ -341,29 +380,54 @@ function resolveLabelMatcher(node: SyntaxNode, text: string, pos: number): Situa
|
||||
// we need to remove "our" label from all-labels, if it is in there
|
||||
const otherLabels = allLabels.filter((label) => label.name !== labelName);
|
||||
|
||||
const metricNameNode = walk(labelMatchersNode, [
|
||||
['parent', VectorSelector],
|
||||
['firstChild', Identifier],
|
||||
]);
|
||||
|
||||
if (metricNameNode === null) {
|
||||
// we are probably in a situation without a metric name
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
labelName,
|
||||
betweenQuotes: inStringNode,
|
||||
otherLabels,
|
||||
};
|
||||
}
|
||||
|
||||
const metricName = getNodeText(metricNameNode, text);
|
||||
const metricName = getMetricName(labelMatchersNode, text);
|
||||
|
||||
// we are probably in a situation without a metric name
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
metricName,
|
||||
labelName,
|
||||
betweenQuotes: inStringNode,
|
||||
otherLabels,
|
||||
...(metricName ? { metricName } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function resolveQuotedLabelMatcher(node: SyntaxNode, text: string, pos: number): Situation | null {
|
||||
// we can arrive here in two situation. `node` is either:
|
||||
// - a StringNode (like in `{"job"="^"}`)
|
||||
// - or an error node (like in `{"job"=^}`)
|
||||
const inStringNode = !node.type.isError;
|
||||
|
||||
const parent = walk(node, [['parent', QuotedLabelMatcher]]);
|
||||
if (parent === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const labelNameNode = walk(parent, [['firstChild', QuotedLabelName]]);
|
||||
if (labelNameNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const labelName = getNodeText(labelNameNode, text);
|
||||
|
||||
const labelMatchersNode = walk(parent, [['parent', LabelMatchers]]);
|
||||
if (labelMatchersNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// now we need to find the other names
|
||||
const allLabels = getLabels(labelMatchersNode, text);
|
||||
|
||||
// we need to remove "our" label from all-labels, if it is in there
|
||||
const otherLabels = allLabels.filter((label) => label.name !== labelName);
|
||||
const metricName = getMetricName(parent.parent!, text);
|
||||
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_WITH_LABEL_NAME',
|
||||
labelName,
|
||||
betweenQuotes: inStringNode,
|
||||
otherLabels,
|
||||
...(metricName ? { metricName } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -388,7 +452,7 @@ function resolveDurations(node: SyntaxNode, text: string, pos: number): Situatio
|
||||
function resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Situation | null {
|
||||
// next false positive:
|
||||
// `something{a="1"^}`
|
||||
const child = walk(node, [['firstChild', UnquotedLabelMatcher]]);
|
||||
let child = walk(node, [['firstChild', UnquotedLabelMatcher]]);
|
||||
if (child !== null) {
|
||||
// means the label-matching part contains at least one label already.
|
||||
//
|
||||
@@ -403,28 +467,72 @@ function resolveLabelKeysWithEquals(node: SyntaxNode, text: string, pos: number)
|
||||
}
|
||||
}
|
||||
|
||||
const metricNameNode = walk(node, [
|
||||
// next false positive:
|
||||
// `{"utf8.metric"^}`
|
||||
child = walk(node, [['firstChild', QuotedLabelName]]);
|
||||
if (child !== null) {
|
||||
// means the label-matching part contains a utf8 metric.
|
||||
//
|
||||
// in this case, we will need to have a `,` character at the end,
|
||||
// to be able to suggest adding the next label.
|
||||
// the area between the end-of-the-child-node and the cursor-pos
|
||||
// must contain a `,` in this case.
|
||||
const textToCheck = text.slice(child.to, pos);
|
||||
|
||||
if (!textToCheck.includes(',')) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const otherLabels = getLabels(node, text);
|
||||
const metricName = getMetricName(node, text);
|
||||
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels,
|
||||
betweenQuotes: false,
|
||||
...(metricName ? { metricName } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function resolveUtf8LabelKeysWithEquals(node: SyntaxNode, text: string, pos: number): Situation | null {
|
||||
const otherLabels = getLabels(node, text);
|
||||
const metricName = node.parent?.parent ? getMetricName(node.parent.parent, text) : null;
|
||||
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels,
|
||||
betweenQuotes: true,
|
||||
...(metricName ? { metricName } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function getMetricName(node: SyntaxNode, text: string): string | null {
|
||||
// Legacy Metric metric_name{label="value"}
|
||||
const legacyMetricNameNode = walk(node, [
|
||||
['parent', VectorSelector],
|
||||
['firstChild', Identifier],
|
||||
]);
|
||||
|
||||
const otherLabels = getLabels(node, text);
|
||||
|
||||
if (metricNameNode === null) {
|
||||
// we are probably in a situation without a metric name.
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
otherLabels,
|
||||
};
|
||||
if (legacyMetricNameNode) {
|
||||
return getNodeText(legacyMetricNameNode, text);
|
||||
}
|
||||
|
||||
const metricName = getNodeText(metricNameNode, text);
|
||||
// check for a utf-8 metric
|
||||
// utf-8 metric {"metric.name", label="value"}
|
||||
const utf8MetricNameNode = walk(node, [
|
||||
['parent', VectorSelector],
|
||||
['firstChild', LabelMatchers],
|
||||
['firstChild', QuotedLabelName],
|
||||
['firstChild', StringLiteral],
|
||||
]);
|
||||
|
||||
return {
|
||||
type: 'IN_LABEL_SELECTOR_NO_LABEL_NAME',
|
||||
metricName,
|
||||
otherLabels,
|
||||
};
|
||||
if (utf8MetricNameNode) {
|
||||
return getNodeText(utf8MetricNameNode, text, true);
|
||||
}
|
||||
|
||||
// no metric name
|
||||
return null;
|
||||
}
|
||||
|
||||
// we find the first error-node in the tree that is at the cursor-position.
|
||||
@@ -461,10 +569,10 @@ export function getSituation(text: string, pos: number): Situation | null {
|
||||
}
|
||||
|
||||
/**
|
||||
PromQL
|
||||
Expr
|
||||
VectorSelector
|
||||
LabelMatchers
|
||||
PromQL
|
||||
Expr
|
||||
VectorSelector
|
||||
LabelMatchers
|
||||
*/
|
||||
const tree = parser.parse(text);
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ import {
|
||||
RawRecordingRules,
|
||||
RuleQueryMapping,
|
||||
} from './types';
|
||||
import { utf8Support, wrapUtf8Filters } from './utf8_support';
|
||||
import { PrometheusVariableSupport } from './variables';
|
||||
|
||||
const ANNOTATION_QUERY_STEP_DEFAULT = '60s';
|
||||
@@ -925,7 +926,21 @@ export class PrometheusDatasource
|
||||
|
||||
// We need a first replace to evaluate variables before applying adhoc filters
|
||||
// This is required for an expression like `metric > $VAR` where $VAR is a float to which we must not add adhoc filters
|
||||
const expr = this.templateSrv.replace(target.expr, variables, this.interpolateQueryExpr);
|
||||
const expr = this.templateSrv.replace(
|
||||
target.expr,
|
||||
variables,
|
||||
(value: string | string[] = [], variable: QueryVariableModel | CustomVariableModel) => {
|
||||
if (typeof value === 'string' && target.fromExploreMetrics) {
|
||||
if (variable.name === 'filters') {
|
||||
return wrapUtf8Filters(value);
|
||||
}
|
||||
if (variable.name === 'groupby') {
|
||||
return utf8Support(value);
|
||||
}
|
||||
}
|
||||
return this.interpolateQueryExpr(value, variable);
|
||||
}
|
||||
);
|
||||
|
||||
// Apply ad-hoc filters
|
||||
// When ad-hoc filters are applied, we replace again the variables in case the ad-hoc filters also reference a variable
|
||||
|
||||
@@ -85,3 +85,11 @@ export {
|
||||
type StandardPromVariableQuery,
|
||||
} from './types';
|
||||
export { PrometheusVariableSupport } from './variables';
|
||||
|
||||
// For explore metrics
|
||||
export { default as PromQlLanguageProvider } from './language_provider';
|
||||
export { getPrometheusTime } from './language_utils';
|
||||
export { isValidLegacyName, utf8Support, wrapUtf8Filters } from './utf8_support';
|
||||
export { buildVisualQueryFromString } from './querybuilder/parsing';
|
||||
export { PromQueryModeller } from './querybuilder/PromQueryModeller';
|
||||
export { type QueryBuilderLabelFilter } from './querybuilder/shared/types';
|
||||
@@ -4,7 +4,7 @@ import { AbstractLabelOperator, dateTime, TimeRange } from '@grafana/data';
|
||||
import { DEFAULT_SERIES_LIMIT } from './components/PrometheusMetricsBrowser';
|
||||
import { Label } from './components/monaco-query-field/monaco-completion-provider/situation';
|
||||
import { PrometheusDatasource } from './datasource';
|
||||
import LanguageProvider from './language_provider';
|
||||
import LanguageProvider, { removeQuotesIfExist } from './language_provider';
|
||||
import { getClientCacheDurationInMinutes, getPrometheusTime, getRangeSnapInterval } from './language_utils';
|
||||
import { PrometheusCacheLevel, PromQuery } from './types';
|
||||
|
||||
@@ -120,7 +120,13 @@ describe('Language completion provider', () => {
|
||||
|
||||
const labelName = 'job';
|
||||
const labelValue = 'grafana';
|
||||
getSeriesLabels(`{${labelName}="${labelValue}"}`, [{ name: labelName, value: labelValue, op: '=' }] as Label[]);
|
||||
getSeriesLabels(`{${labelName}="${labelValue}"}`, [
|
||||
{
|
||||
name: labelName,
|
||||
value: labelValue,
|
||||
op: '=',
|
||||
},
|
||||
] as Label[]);
|
||||
expect(requestSpy).toHaveBeenCalled();
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
`/api/v1/labels`,
|
||||
@@ -145,7 +151,13 @@ describe('Language completion provider', () => {
|
||||
|
||||
const labelName = 'job';
|
||||
const labelValue = 'grafana';
|
||||
getSeriesLabels(`{${labelName}="${labelValue}"}`, [{ name: labelName, value: labelValue, op: '=' }] as Label[]);
|
||||
getSeriesLabels(`{${labelName}="${labelValue}"}`, [
|
||||
{
|
||||
name: labelName,
|
||||
value: labelValue,
|
||||
op: '=',
|
||||
},
|
||||
] as Label[]);
|
||||
expect(requestSpy).toHaveBeenCalled();
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
'/api/v1/series',
|
||||
@@ -174,7 +186,13 @@ describe('Language completion provider', () => {
|
||||
|
||||
const labelName = 'job';
|
||||
const labelValue = 'grafana';
|
||||
getSeriesLabels(`{${labelName}="${labelValue}"}`, [{ name: labelName, value: labelValue, op: '=' }] as Label[]);
|
||||
getSeriesLabels(`{${labelName}="${labelValue}"}`, [
|
||||
{
|
||||
name: labelName,
|
||||
value: labelValue,
|
||||
op: '=',
|
||||
},
|
||||
] as Label[]);
|
||||
expect(requestSpy).toHaveBeenCalled();
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
`/api/v1/labels`,
|
||||
@@ -569,14 +587,14 @@ describe('Language completion provider', () => {
|
||||
it('should interpolate variable in series', () => {
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
interpolateString: (string: string) => string.replace(/\$/, 'interpolated-'),
|
||||
interpolateString: (string: string) => string.replace(/\$/g, 'interpolated_'),
|
||||
} as PrometheusDatasource);
|
||||
const fetchLabelValues = languageProvider.fetchLabelValues;
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
fetchLabelValues('$job');
|
||||
expect(requestSpy).toHaveBeenCalled();
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
'/api/v1/label/interpolated-job/values',
|
||||
'/api/v1/label/interpolated_job/values',
|
||||
[],
|
||||
{
|
||||
end: toPrometheusTimeString,
|
||||
@@ -585,6 +603,69 @@ describe('Language completion provider', () => {
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it('should fetch with encoded utf8 label', () => {
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
interpolateString: (string: string) => string.replace(/\$/g, 'http.status:sum'),
|
||||
} as PrometheusDatasource);
|
||||
const fetchLabelValues = languageProvider.fetchLabelValues;
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
fetchLabelValues('"http.status:sum"');
|
||||
expect(requestSpy).toHaveBeenCalled();
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
'/api/v1/label/U__http_2e_status:sum/values',
|
||||
[],
|
||||
{
|
||||
end: toPrometheusTimeString,
|
||||
start: fromPrometheusTimeString,
|
||||
},
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchSeriesValuesWithMatch', () => {
|
||||
it('should fetch with encoded utf8 label', () => {
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
interpolateString: (string: string) => string.replace(/\$/g, 'http.status:sum'),
|
||||
} as PrometheusDatasource);
|
||||
const fetchSeriesValuesWithMatch = languageProvider.fetchSeriesValuesWithMatch;
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
fetchSeriesValuesWithMatch('"http.status:sum"', '{__name__="a_utf8_http_requests_total"}');
|
||||
expect(requestSpy).toHaveBeenCalled();
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
'/api/v1/label/U__http_2e_status:sum/values',
|
||||
[],
|
||||
{
|
||||
end: toPrometheusTimeString,
|
||||
start: fromPrometheusTimeString,
|
||||
'match[]': '{__name__="a_utf8_http_requests_total"}',
|
||||
},
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it('should fetch without encoding for standard prometheus labels', () => {
|
||||
const languageProvider = new LanguageProvider({
|
||||
...defaultDatasource,
|
||||
} as PrometheusDatasource);
|
||||
const fetchSeriesValuesWithMatch = languageProvider.fetchSeriesValuesWithMatch;
|
||||
const requestSpy = jest.spyOn(languageProvider, 'request');
|
||||
fetchSeriesValuesWithMatch('"http_status_sum"', '{__name__="a_utf8_http_requests_total"}');
|
||||
expect(requestSpy).toHaveBeenCalled();
|
||||
expect(requestSpy).toHaveBeenCalledWith(
|
||||
'/api/v1/label/http_status_sum/values',
|
||||
[],
|
||||
{
|
||||
end: toPrometheusTimeString,
|
||||
start: fromPrometheusTimeString,
|
||||
'match[]': '{__name__="a_utf8_http_requests_total"}',
|
||||
},
|
||||
undefined
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('disabled metrics lookup', () => {
|
||||
@@ -650,3 +731,59 @@ describe('Language completion provider', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('removeQuotesIfExist', () => {
|
||||
it('removes quotes from a string with double quotes', () => {
|
||||
const input = '"hello"';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('hello');
|
||||
});
|
||||
|
||||
it('returns the original string if it does not start and end with quotes', () => {
|
||||
const input = 'hello';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('hello');
|
||||
});
|
||||
|
||||
it('returns the original string if it has mismatched quotes', () => {
|
||||
const input = '"hello';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('"hello');
|
||||
});
|
||||
|
||||
it('removes quotes for strings with special characters inside quotes', () => {
|
||||
const input = '"hello, world!"';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('hello, world!');
|
||||
});
|
||||
|
||||
it('removes quotes for strings with spaces inside quotes', () => {
|
||||
const input = '" "';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe(' ');
|
||||
});
|
||||
|
||||
it('returns the original string for an empty string', () => {
|
||||
const input = '';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('');
|
||||
});
|
||||
|
||||
it('returns the original string if the string only has a single quote character', () => {
|
||||
const input = '"';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('"');
|
||||
});
|
||||
|
||||
it('handles strings with nested quotes correctly', () => {
|
||||
const input = '"nested \"quotes\""';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('nested \"quotes\"');
|
||||
});
|
||||
|
||||
it('removes quotes from a numeric string wrapped in quotes', () => {
|
||||
const input = '"12345"';
|
||||
const result = removeQuotesIfExist(input);
|
||||
expect(result).toBe('12345');
|
||||
});
|
||||
});
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
import PromqlSyntax from './promql';
|
||||
import { buildVisualQueryFromString } from './querybuilder/parsing';
|
||||
import { PrometheusCacheLevel, PromMetricsMetadata, PromQuery } from './types';
|
||||
import { escapeForUtf8Support, isValidLegacyName } from './utf8_support';
|
||||
|
||||
const DEFAULT_KEYS = ['job', 'instance'];
|
||||
const EMPTY_SELECTOR = '{}';
|
||||
@@ -208,7 +209,8 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
fetchLabelValues = async (key: string): Promise<string[]> => {
|
||||
const params = this.datasource.getAdjustedInterval(this.timeRange);
|
||||
const interpolatedName = this.datasource.interpolateString(key);
|
||||
const url = `/api/v1/label/${interpolatedName}/values`;
|
||||
const interpolatedAndEscapedName = escapeForUtf8Support(removeQuotesIfExist(interpolatedName));
|
||||
const url = `/api/v1/label/${interpolatedAndEscapedName}/values`;
|
||||
const value = await this.request(url, [], params, this.getDefaultCacheHeaders());
|
||||
return value ?? [];
|
||||
};
|
||||
@@ -232,10 +234,11 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
queries?.forEach((q) => {
|
||||
const visualQuery = buildVisualQueryFromString(q.expr);
|
||||
if (visualQuery.query.metric !== '') {
|
||||
searchParams.append('match[]', visualQuery.query.metric);
|
||||
const isUtf8Metric = !isValidLegacyName(visualQuery.query.metric);
|
||||
searchParams.append('match[]', isUtf8Metric ? `{"${visualQuery.query.metric}"}` : visualQuery.query.metric);
|
||||
if (visualQuery.query.binaryQueries) {
|
||||
visualQuery.query.binaryQueries.forEach((bq) => {
|
||||
searchParams.append('match[]', bq.query.metric);
|
||||
searchParams.append('match[]', isUtf8Metric ? `{"${bq.query.metric}"}` : bq.query.metric);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -263,7 +266,7 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
getSeriesValues = async (labelName: string, selector: string): Promise<string[]> => {
|
||||
if (!this.datasource.hasLabelsMatchAPISupport()) {
|
||||
const data = await this.getSeries(selector);
|
||||
return data[labelName] ?? [];
|
||||
return data[removeQuotesIfExist(labelName)] ?? [];
|
||||
}
|
||||
return await this.fetchSeriesValuesWithMatch(labelName, selector);
|
||||
};
|
||||
@@ -297,7 +300,14 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
requestOptions = undefined;
|
||||
}
|
||||
|
||||
const value = await this.request(`/api/v1/label/${interpolatedName}/values`, [], urlParams, requestOptions);
|
||||
const interpolatedAndEscapedName = escapeForUtf8Support(removeQuotesIfExist(interpolatedName ?? ''));
|
||||
|
||||
const value = await this.request(
|
||||
`/api/v1/label/${interpolatedAndEscapedName}/values`,
|
||||
[],
|
||||
urlParams,
|
||||
requestOptions
|
||||
);
|
||||
return value ?? [];
|
||||
};
|
||||
|
||||
@@ -493,3 +503,10 @@ function isCancelledError(error: unknown): error is {
|
||||
} {
|
||||
return typeof error === 'object' && error !== null && 'cancelled' in error && error.cancelled === true;
|
||||
}
|
||||
|
||||
// For utf8 labels we use quotes around the label
|
||||
// While requesting the label values we must remove the quotes
|
||||
export function removeQuotesIfExist(input: string): string {
|
||||
const match = input.match(/^"(.*)"$/); // extract the content inside the quotes
|
||||
return match?.[1] ?? input;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
getPrometheusTime,
|
||||
getRangeSnapInterval,
|
||||
parseSelector,
|
||||
processLabels,
|
||||
toPromLikeQuery,
|
||||
truncateResult,
|
||||
} from './language_utils';
|
||||
@@ -565,3 +566,54 @@ describe('truncateResult', () => {
|
||||
expect(array[999]).toBe(999);
|
||||
});
|
||||
});
|
||||
|
||||
describe('processLabels', () => {
|
||||
it('export abstract query to expr', () => {
|
||||
const labels: Array<{ [key: string]: string }> = [
|
||||
{ label1: 'value1' },
|
||||
{ label2: 'value2' },
|
||||
{ label3: 'value3' },
|
||||
{ label1: 'value1' },
|
||||
{ label1: 'value1b' },
|
||||
];
|
||||
|
||||
expect(processLabels(labels)).toEqual({
|
||||
keys: ['label1', 'label2', 'label3'],
|
||||
values: { label1: ['value1', 'value1b'], label2: ['value2'], label3: ['value3'] },
|
||||
});
|
||||
});
|
||||
|
||||
it('dont wrap utf8 label values with quotes', () => {
|
||||
const labels: Array<{ [key: string]: string }> = [
|
||||
{ label1: 'value1' },
|
||||
{ label2: 'value2' },
|
||||
{ label3: 'value3 with space' },
|
||||
{ label4: 'value4.with.dot' },
|
||||
];
|
||||
|
||||
expect(processLabels(labels)).toEqual({
|
||||
keys: ['label1', 'label2', 'label3', 'label4'],
|
||||
values: {
|
||||
label1: ['value1'],
|
||||
label2: ['value2'],
|
||||
label3: [`value3 with space`],
|
||||
label4: [`value4.with.dot`],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('dont wrap utf8 labels with quotes', () => {
|
||||
const labels: Array<{ [key: string]: string }> = [
|
||||
{ 'label1 with space': 'value1' },
|
||||
{ 'label2.with.dot': 'value2' },
|
||||
];
|
||||
|
||||
expect(processLabels(labels)).toEqual({
|
||||
keys: ['label1 with space', 'label2.with.dot'],
|
||||
values: {
|
||||
'label1 with space': ['value1'],
|
||||
'label2.with.dot': ['value2'],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -478,7 +478,10 @@ export function extractLabelMatchers(tokens: Array<string | Token>): AbstractLab
|
||||
export function getRangeSnapInterval(
|
||||
cacheLevel: PrometheusCacheLevel,
|
||||
range: TimeRange
|
||||
): { start: string; end: string } {
|
||||
): {
|
||||
start: string;
|
||||
end: string;
|
||||
} {
|
||||
// Don't round the range if we're not caching
|
||||
if (cacheLevel === PrometheusCacheLevel.None) {
|
||||
return {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { PrometheusDatasource } from './datasource';
|
||||
import { getPrometheusTime } from './language_utils';
|
||||
import { PrometheusMetricFindQuery } from './metric_find_query';
|
||||
import { PromApplication, PromOptions } from './types';
|
||||
import { escapeForUtf8Support } from './utf8_support';
|
||||
|
||||
const fetchMock = jest.fn((options: BackendSrvRequest): Observable<FetchResponse<BackendDataSourceResponse>> => {
|
||||
return of({} as unknown as FetchResponse);
|
||||
@@ -413,5 +414,51 @@ describe('PrometheusMetricFindQuery', () => {
|
||||
});
|
||||
});
|
||||
// </ ModernPrometheus>
|
||||
describe('utf8 metric and label support', () => {
|
||||
it('utf8 label - label_values(a_utf8_http_requests_total,instance.test) should generate label values query', () => {
|
||||
const metricName = 'a_utf8_http_requests_total';
|
||||
const label = 'instance.test';
|
||||
const query = `label_values(${metricName},${label})`;
|
||||
const metricFindQuery = new PrometheusMetricFindQuery(prometheusDatasource, query);
|
||||
metricFindQuery.process(raw);
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/uid/ABCDEF/resources/api/v1/label/${escapeForUtf8Support(label)}/values?match%5B%5D=${metricName}&start=1524650400&end=1524654000`,
|
||||
hideFromInspector: true,
|
||||
headers: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('utf8 metric - label_values(utf8.http_requests_total,instance_test) should generate label values query', () => {
|
||||
const metricName = 'utf8.http_requests_total';
|
||||
const label = 'instance_test';
|
||||
const query = `label_values(${metricName},${label})`;
|
||||
const metricFindQuery = new PrometheusMetricFindQuery(prometheusDatasource, query);
|
||||
metricFindQuery.process(raw);
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/uid/ABCDEF/resources/api/v1/label/${label}/values?match%5B%5D=${metricName}&start=1524650400&end=1524654000`,
|
||||
hideFromInspector: true,
|
||||
headers: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('utf8 metric and label - label_values(utf8.http_requests_total,instance.test) should generate label values query', () => {
|
||||
const metricName = 'utf8.http_requests_total';
|
||||
const label = 'instance.test';
|
||||
const query = `label_values(${metricName},${label})`;
|
||||
const metricFindQuery = new PrometheusMetricFindQuery(prometheusDatasource, query);
|
||||
metricFindQuery.process(raw);
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith({
|
||||
method: 'GET',
|
||||
url: `/api/datasources/uid/ABCDEF/resources/api/v1/label/${escapeForUtf8Support(label)}/values?match%5B%5D=${metricName}&start=1524650400&end=1524654000`,
|
||||
hideFromInspector: true,
|
||||
headers: {},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,9 +8,11 @@ import { getPrometheusTime } from './language_utils';
|
||||
import {
|
||||
PrometheusLabelNamesRegex,
|
||||
PrometheusLabelNamesRegexWithMatch,
|
||||
PrometheusLabelValuesRegex,
|
||||
PrometheusMetricNamesRegex,
|
||||
PrometheusQueryResultRegex,
|
||||
} from './migrations/variableMigration';
|
||||
import { escapeForUtf8Support, isValidLegacyName } from './utf8_support';
|
||||
|
||||
export class PrometheusMetricFindQuery {
|
||||
range: TimeRange;
|
||||
@@ -28,7 +30,7 @@ export class PrometheusMetricFindQuery {
|
||||
this.range = timeRange;
|
||||
const labelNamesRegex = PrometheusLabelNamesRegex;
|
||||
const labelNamesRegexWithMatch = PrometheusLabelNamesRegexWithMatch;
|
||||
const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\)\s*$/;
|
||||
const labelValuesRegex = PrometheusLabelValuesRegex;
|
||||
const metricNamesRegex = PrometheusMetricNamesRegex;
|
||||
const queryResultRegex = PrometheusQueryResultRegex;
|
||||
const labelNamesQuery = this.query.match(labelNamesRegex);
|
||||
@@ -83,8 +85,13 @@ export class PrometheusMetricFindQuery {
|
||||
const end = getPrometheusTime(this.range.to, true);
|
||||
const params = { ...(metric && { 'match[]': metric }), start: start.toString(), end: end.toString() };
|
||||
|
||||
let escapedLabel = label;
|
||||
if (!isValidLegacyName(label)) {
|
||||
escapedLabel = escapeForUtf8Support(label);
|
||||
}
|
||||
|
||||
if (!metric || this.datasource.hasLabelsMatchAPISupport()) {
|
||||
const url = `/api/v1/label/${label}/values`;
|
||||
const url = `/api/v1/label/${escapedLabel}/values`;
|
||||
|
||||
return this.datasource.metadataRequest(url, params).then((result) => {
|
||||
return _map(result.data.data, (value) => {
|
||||
|
||||
@@ -4,8 +4,7 @@ import { buildVisualQueryFromString } from '../querybuilder/parsing';
|
||||
import { PromVariableQuery, PromVariableQueryType as QueryType } from '../types';
|
||||
|
||||
export const PrometheusLabelNamesRegex = /^label_names\(\)\s*$/;
|
||||
// Note that this regex is different from the one in metric_find_query.ts because this is used pre-interpolation
|
||||
export const PrometheusLabelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_$][a-zA-Z0-9_]*)\)\s*$/;
|
||||
export const PrometheusLabelValuesRegex = /^label_values\((?:(.+),\s*)?(.+)\)\s*$/;
|
||||
export const PrometheusMetricNamesRegex = /^metrics\((.+)\)\s*$/;
|
||||
export const PrometheusQueryResultRegex = /^query_result\((.+)\)\s*$/;
|
||||
export const PrometheusLabelNamesRegexWithMatch = /^label_names\((.+)\)\s*$/;
|
||||
@@ -97,7 +96,7 @@ export function migrateVariableQueryToEditor(rawQuery: string | PromVariableQuer
|
||||
return queryBase;
|
||||
}
|
||||
|
||||
// migrate it back to a string with the correct varialbes in place
|
||||
// migrate it back to a string with the correct variables in place
|
||||
export function migrateVariableEditorBackToVariableSupport(QueryVariable: PromVariableQuery): string {
|
||||
switch (QueryVariable.qryType) {
|
||||
case QueryType.LabelNames:
|
||||
|
||||
@@ -334,3 +334,82 @@ describe('PromQueryModeller', () => {
|
||||
).toBe('cluster_namespace_slug_dialer_name <= bool 2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('PromQueryModeller with utf8 support', () => {
|
||||
const modeller = new PromQueryModeller();
|
||||
|
||||
it('should render nothing if there is nothing', () => {
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
metric: undefined,
|
||||
labels: [],
|
||||
operations: [],
|
||||
})
|
||||
).toBe('');
|
||||
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
metric: '',
|
||||
labels: [],
|
||||
operations: [],
|
||||
})
|
||||
).toBe('');
|
||||
});
|
||||
|
||||
it('should render legacy metric name as usual', () => {
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
metric: 'not_a_utf8_metric',
|
||||
labels: [],
|
||||
operations: [],
|
||||
})
|
||||
).toBe('not_a_utf8_metric');
|
||||
});
|
||||
|
||||
it('can render utf8 metric name in curly braces', () => {
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
metric: 'a.utf8.metric',
|
||||
labels: [],
|
||||
operations: [],
|
||||
})
|
||||
).toBe('{"a.utf8.metric"}');
|
||||
});
|
||||
|
||||
it('can render utf8 metric name in curly braces with legacy labels', () => {
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
metric: 'a.utf8.metric',
|
||||
labels: [
|
||||
{
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
op: '=',
|
||||
},
|
||||
],
|
||||
operations: [],
|
||||
})
|
||||
).toBe('{"a.utf8.metric", label="value"}');
|
||||
});
|
||||
|
||||
it('can render utf8 metric name in curly braces with legacy and utf8 labels', () => {
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
metric: 'a.utf8.metric',
|
||||
labels: [
|
||||
{
|
||||
label: 'label',
|
||||
value: 'value',
|
||||
op: '=',
|
||||
},
|
||||
{
|
||||
label: 'utf8.label',
|
||||
value: 'value',
|
||||
op: '=',
|
||||
},
|
||||
],
|
||||
operations: [],
|
||||
})
|
||||
).toBe('{"a.utf8.metric", label="value", "utf8.label"="value"}');
|
||||
});
|
||||
});
|
||||
@@ -93,7 +93,7 @@ export const PromQueryBuilder = memo<PromQueryBuilderProps>((props) => {
|
||||
{showExplain && (
|
||||
<OperationExplainedBox
|
||||
stepNumber={1}
|
||||
title={<RawQuery query={`${query.metric} ${promQueryModeller.renderLabels(query.labels)}`} lang={lang} />}
|
||||
title={<RawQuery query={`${promQueryModeller.renderQuery(query)}`} lang={lang} />}
|
||||
>
|
||||
{EXPLAIN_LABEL_FILTER_CONTENT}
|
||||
</OperationExplainedBox>
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ export const PromQueryBuilderExplained = memo<PromQueryBuilderExplainedProps>(({
|
||||
<Stack gap={0.5} direction="column">
|
||||
<OperationExplainedBox
|
||||
stepNumber={1}
|
||||
title={<RawQuery query={`${visQuery.metric} ${promQueryModeller.renderLabels(visQuery.labels)}`} lang={lang} />}
|
||||
title={<RawQuery query={`${promQueryModeller.renderQuery(visQuery)}`} lang={lang} />}
|
||||
>
|
||||
{EXPLAIN_LABEL_FILTER_CONTENT}
|
||||
</OperationExplainedBox>
|
||||
|
||||
@@ -3,6 +3,80 @@ import { buildVisualQueryFromString } from './parsing';
|
||||
import { PromOperationId, PromVisualQuery } from './types';
|
||||
|
||||
describe('buildVisualQueryFromString', () => {
|
||||
describe('utf8 support', () => {
|
||||
it('supports uts-8 label names', () => {
|
||||
expect(buildVisualQueryFromString('{"glück:🍀.dot"="luck"} == 11')).toEqual({
|
||||
query: {
|
||||
labels: [
|
||||
{
|
||||
label: 'glück:🍀.dot',
|
||||
op: '=',
|
||||
value: 'luck',
|
||||
},
|
||||
],
|
||||
metric: '',
|
||||
operations: [
|
||||
{
|
||||
id: PromOperationId.EqualTo,
|
||||
params: [11, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('supports uts-8 metric names', () => {
|
||||
expect(buildVisualQueryFromString('{"I am a metric"}')).toEqual({
|
||||
query: {
|
||||
labels: [],
|
||||
metric: 'I am a metric',
|
||||
operations: [],
|
||||
},
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('supports uts-8 metric names with labels', () => {
|
||||
expect(buildVisualQueryFromString('{"metric.name", label_field="label value"}')).toEqual({
|
||||
query: {
|
||||
labels: [
|
||||
{
|
||||
label: 'label_field',
|
||||
op: '=',
|
||||
value: 'label value',
|
||||
},
|
||||
],
|
||||
metric: 'metric.name',
|
||||
operations: [],
|
||||
},
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('supports uts-8 metric names with utf8 labels', () => {
|
||||
expect(buildVisualQueryFromString('{"metric.name", "glück:🍀.dot"="luck"} == 11')).toEqual({
|
||||
query: {
|
||||
labels: [
|
||||
{
|
||||
label: 'glück:🍀.dot',
|
||||
op: '=',
|
||||
value: 'luck',
|
||||
},
|
||||
],
|
||||
metric: 'metric.name',
|
||||
operations: [
|
||||
{
|
||||
id: PromOperationId.EqualTo,
|
||||
params: [11, false],
|
||||
},
|
||||
],
|
||||
},
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('creates no errors for empty query', () => {
|
||||
expect(buildVisualQueryFromString('')).toEqual(
|
||||
noErrors({
|
||||
@@ -246,6 +320,31 @@ describe('buildVisualQueryFromString', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('parses query with aggregation by utf8 labels', () => {
|
||||
const visQuery = {
|
||||
metric: 'metric_name',
|
||||
labels: [
|
||||
{
|
||||
label: 'instance',
|
||||
op: '=',
|
||||
value: 'internal:3000',
|
||||
},
|
||||
],
|
||||
operations: [
|
||||
{
|
||||
id: '__sum_by',
|
||||
params: ['cluster', '"app.version"'],
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(
|
||||
buildVisualQueryFromString('sum(metric_name{instance="internal:3000"}) by ("app.version", cluster)')
|
||||
).toEqual(noErrors(visQuery));
|
||||
expect(
|
||||
buildVisualQueryFromString('sum by ("app.version", cluster)(metric_name{instance="internal:3000"})')
|
||||
).toEqual(noErrors(visQuery));
|
||||
});
|
||||
|
||||
it('parses aggregation with params', () => {
|
||||
expect(buildVisualQueryFromString('topk(5, http_requests_total)')).toEqual(
|
||||
noErrors({
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
GroupingLabels,
|
||||
Identifier,
|
||||
LabelName,
|
||||
QuotedLabelName,
|
||||
MatchingModifierClause,
|
||||
MatchOp,
|
||||
NumberDurationLiteral,
|
||||
@@ -19,6 +20,7 @@ import {
|
||||
ParenExpr,
|
||||
parser,
|
||||
StringLiteral,
|
||||
QuotedLabelMatcher,
|
||||
UnquotedLabelMatcher,
|
||||
VectorSelector,
|
||||
Without,
|
||||
@@ -145,9 +147,33 @@ export function handleExpression(expr: string, node: SyntaxNode, context: Contex
|
||||
break;
|
||||
}
|
||||
|
||||
case QuotedLabelName: {
|
||||
// Usually we got the metric name above in the Identifier case.
|
||||
// If we didn't get the name that's potentially we have it in curly braces as quoted string.
|
||||
// It must be quoted because that's how utf8 metric names should be defined
|
||||
// See proposal https://github.com/prometheus/proposals/blob/main/proposals/2023-08-21-utf8.md
|
||||
if (visQuery.metric === '') {
|
||||
const strLiteral = node.getChild(StringLiteral);
|
||||
const quotedMetric = getString(expr, strLiteral);
|
||||
visQuery.metric = quotedMetric.slice(1, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QuotedLabelMatcher: {
|
||||
const quotedLabel = getLabel(expr, node, QuotedLabelName);
|
||||
quotedLabel.label = quotedLabel.label.slice(1, -1);
|
||||
visQuery.labels.push(quotedLabel);
|
||||
const err = node.getChild(ErrorId);
|
||||
if (err) {
|
||||
context.errors.push(makeError(expr, err));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case UnquotedLabelMatcher: {
|
||||
// Same as MetricIdentifier should be just one per query.
|
||||
visQuery.labels.push(getLabel(expr, node));
|
||||
visQuery.labels.push(getLabel(expr, node, LabelName));
|
||||
const err = node.getChild(ErrorId);
|
||||
if (err) {
|
||||
context.errors.push(makeError(expr, err));
|
||||
@@ -202,8 +228,12 @@ function isIntervalVariableError(node: SyntaxNode) {
|
||||
return node.prevSibling?.firstChild?.type.id === VectorSelector;
|
||||
}
|
||||
|
||||
function getLabel(expr: string, node: SyntaxNode): QueryBuilderLabelFilter {
|
||||
const label = getString(expr, node.getChild(LabelName));
|
||||
function getLabel(
|
||||
expr: string,
|
||||
node: SyntaxNode,
|
||||
labelType: typeof LabelName | typeof QuotedLabelName
|
||||
): QueryBuilderLabelFilter {
|
||||
const label = getString(expr, node.getChild(labelType));
|
||||
const op = getString(expr, node.getChild(MatchOp));
|
||||
const value = getString(expr, node.getChild(StringLiteral)).replace(/^["'`]|["'`]$/g, '');
|
||||
return {
|
||||
@@ -281,7 +311,7 @@ function handleAggregation(expr: string, node: SyntaxNode, context: Context) {
|
||||
funcName = `__${funcName}_without`;
|
||||
}
|
||||
|
||||
labels.push(...getAllByType(expr, modifier, LabelName));
|
||||
labels.push(...getAllByType(expr, modifier, LabelName), ...getAllByType(expr, modifier, QuotedLabelName));
|
||||
}
|
||||
|
||||
const body = node.getChild(FunctionCallBody);
|
||||
|
||||
+17
-2
@@ -3,6 +3,7 @@ import { Registry } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import { prometheusRegularEscape } from '../../datasource';
|
||||
import { isValidLegacyName, utf8Support } from '../../utf8_support';
|
||||
import { PromVisualQueryOperationCategory } from '../types';
|
||||
|
||||
import { QueryBuilderLabelFilter, QueryBuilderOperation, QueryBuilderOperationDef, VisualQueryModeller } from './types';
|
||||
@@ -97,14 +98,28 @@ export abstract class LokiAndPromQueryModellerBase implements VisualQueryModelle
|
||||
if (config.featureToggles.prometheusSpecialCharsInLabelValues && !usingRegexOperator) {
|
||||
labelValue = prometheusRegularEscape(labelValue);
|
||||
}
|
||||
expr += `${filter.label}${filter.op}"${labelValue}"`;
|
||||
expr += `${utf8Support(filter.label)}${filter.op}"${labelValue}"`;
|
||||
}
|
||||
|
||||
return expr + `}`;
|
||||
}
|
||||
|
||||
renderQuery(query: PromLokiVisualQuery, nested?: boolean) {
|
||||
let queryString = `${query.metric ?? ''}${this.renderLabels(query.labels)}`;
|
||||
let queryString = '';
|
||||
const labels = this.renderLabels(query.labels);
|
||||
if (query.metric) {
|
||||
if (isValidLegacyName(query.metric)) {
|
||||
// This is a legacy metric, put outside the curl legacy_query{label="value"}
|
||||
queryString = `${query.metric}${labels}`;
|
||||
} else {
|
||||
// This is a utf8 metric, put inside the curly and quotes {"utf8.metric", label="value"}
|
||||
queryString = `{"${query.metric}"${labels.length > 0 ? `, ${labels.substring(1)}` : `}`}`;
|
||||
}
|
||||
} else {
|
||||
// No metric just use labels {label="value"}
|
||||
queryString = labels;
|
||||
}
|
||||
|
||||
queryString = this.renderOperations(queryString, query.operations);
|
||||
|
||||
if (!nested && this.hasBinaryOp(query) && Boolean(query.binaryQueries?.length)) {
|
||||
|
||||
@@ -20,6 +20,7 @@ export interface PromQuery extends GenPromQuery, DataQuery {
|
||||
disableTextWrap?: boolean;
|
||||
fullMetaSearch?: boolean;
|
||||
includeNullMetadata?: boolean;
|
||||
fromExploreMetrics?: boolean;
|
||||
}
|
||||
|
||||
export enum PrometheusCacheLevel {
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { escapeForUtf8Support, utf8Support, wrapUtf8Filters } from './utf8_support';
|
||||
|
||||
describe('utf8 support', () => {
|
||||
it('should return utf8 labels wrapped in quotes', () => {
|
||||
const labels = ['valid:label', 'metric_label', 'utf8 label with space 🤘', ''];
|
||||
const expected = ['valid:label', 'metric_label', `"utf8 label with space 🤘"`, ''];
|
||||
const supportedLabels = labels.map(utf8Support);
|
||||
expect(supportedLabels).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyValueEncodingEscaping', () => {
|
||||
it('should return utf8 labels wrapped in quotes', () => {
|
||||
const labels = [
|
||||
'no:escaping_required',
|
||||
'mysystem.prod.west.cpu.load',
|
||||
'mysystem.prod.west.cpu.load_total',
|
||||
'http.status:sum',
|
||||
'my lovely_http.status:sum',
|
||||
'花火',
|
||||
'label with 😱',
|
||||
];
|
||||
const expected = [
|
||||
'no:escaping_required',
|
||||
'U__mysystem_2e_prod_2e_west_2e_cpu_2e_load',
|
||||
'U__mysystem_2e_prod_2e_west_2e_cpu_2e_load__total',
|
||||
'U__http_2e_status:sum',
|
||||
'U__my_20_lovely__http_2e_status:sum',
|
||||
'U___82b1__706b_',
|
||||
'U__label_20_with_20__1f631_',
|
||||
];
|
||||
const excapedLabels = labels.map(escapeForUtf8Support);
|
||||
expect(excapedLabels).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('wrapUtf8Filters', () => {
|
||||
it('should correctly wrap UTF-8 labels and values for multiple key-value pairs', () => {
|
||||
const result = wrapUtf8Filters('label.with.spaß="this_is_fun",instance="localhost:9112"');
|
||||
const expected = '"label.with.spaß"="this_is_fun",instance="localhost:9112"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly wrap UTF-8 labels and values for a single key-value pair', () => {
|
||||
const result = wrapUtf8Filters('label.with.spaß="this_is_fun"');
|
||||
const expected = '"label.with.spaß"="this_is_fun"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle commas within values', () => {
|
||||
const result = wrapUtf8Filters('label.with.spaß="this,is,fun",instance="localhost:9112"');
|
||||
const expected = '"label.with.spaß"="this,is,fun",instance="localhost:9112"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle escaped quotes within values', () => {
|
||||
const result = wrapUtf8Filters(`label.with.spaß="this_is_\\"fun\\"",instance="localhost:9112"`);
|
||||
const expected = `"label.with.spaß"="this_is_\\"fun\\"",instance="localhost:9112"`;
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle spaces within keys', () => {
|
||||
const result = wrapUtf8Filters('label with space="value with space",instance="localhost:9112"');
|
||||
const expected = '"label with space"="value with space",instance="localhost:9112"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly process mixed inputs with various formats', () => {
|
||||
const result = wrapUtf8Filters('key1="value1",key2="value,with,comma",key3="val3"');
|
||||
const expected = 'key1="value1",key2="value,with,comma",key3="val3"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly handle empty values', () => {
|
||||
const result = wrapUtf8Filters('key1="",key2="value2"');
|
||||
const expected = 'key1="",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle an empty input string', () => {
|
||||
const result = wrapUtf8Filters('');
|
||||
const expected = '';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle a single key with an empty value', () => {
|
||||
const result = wrapUtf8Filters('key1=""');
|
||||
const expected = 'key1=""';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle multiple consecutive commas in a value', () => {
|
||||
const result = wrapUtf8Filters('key1="value1,,value2",key2="value3"');
|
||||
const expected = 'key1="value1,,value2",key2="value3"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle a key-value pair with special characters in the key', () => {
|
||||
const result = wrapUtf8Filters('special@key#="value1",key2="value2"');
|
||||
const expected = '"special@key#"="value1",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle a key-value pair with special characters in the value', () => {
|
||||
const result = wrapUtf8Filters('key1="value@#&*",key2="value2"');
|
||||
const expected = 'key1="value@#&*",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should correctly process keys without special characters', () => {
|
||||
const result = wrapUtf8Filters('key1="value1",key2="value2"');
|
||||
const expected = 'key1="value1",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle nested escaped quotes correctly', () => {
|
||||
const result = wrapUtf8Filters('key1="nested \\"escaped\\" quotes",key2="value2"');
|
||||
const expected = 'key1="nested \\"escaped\\" quotes",key2="value2"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('should handle escaped quotes correctly', () => {
|
||||
const result = wrapUtf8Filters('key1="nested \\"escaped\\" quotes",key2="value with \\"escaped\\" quotes"');
|
||||
const expected = 'key1="nested \\"escaped\\" quotes",key2="value with \\"escaped\\" quotes"';
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,113 @@
|
||||
export const utf8Support = (value: string) => {
|
||||
if (value === '') {
|
||||
return value;
|
||||
}
|
||||
const isLegacyLabel = isValidLegacyName(value);
|
||||
if (isLegacyLabel) {
|
||||
return value;
|
||||
}
|
||||
return `"${value}"`;
|
||||
};
|
||||
|
||||
export const escapeForUtf8Support = (value: string) => {
|
||||
const isLegacyLabel = isValidLegacyName(value);
|
||||
if (isLegacyLabel) {
|
||||
return value;
|
||||
}
|
||||
|
||||
let escaped = 'U__';
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const char = value[i];
|
||||
const codePoint = value.codePointAt(i);
|
||||
|
||||
if (char === '_') {
|
||||
escaped += '__';
|
||||
} else if (codePoint !== undefined && isValidLegacyRune(char, i)) {
|
||||
escaped += char;
|
||||
} else if (codePoint === undefined || !isValidCodePoint(codePoint)) {
|
||||
escaped += '_FFFD_';
|
||||
} else {
|
||||
escaped += '_';
|
||||
escaped += codePoint.toString(16); // Convert code point to hexadecimal
|
||||
escaped += '_';
|
||||
}
|
||||
|
||||
// Handle surrogate pairs for characters outside the Basic Multilingual Plane
|
||||
if (codePoint !== undefined && codePoint > 0xffff) {
|
||||
i++; // Skip the second half of the surrogate pair
|
||||
}
|
||||
}
|
||||
|
||||
return escaped;
|
||||
};
|
||||
|
||||
export const isValidLegacyName = (name: string): boolean => {
|
||||
if (name.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < name.length; i++) {
|
||||
const char = name[i];
|
||||
if (!isValidLegacyRune(char, i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// const labelNamePriorToUtf8Support = /^[a-zA-Z_:][a-zA-Z0-9_:]*$/;
|
||||
// instead of regex we use rune check (converted from prometheus code)
|
||||
// https://github.com/prometheus/common/blob/main/model/metric.go#L426-L428
|
||||
const isValidLegacyRune = (char: string, index: number): boolean => {
|
||||
const codePoint = char.codePointAt(0);
|
||||
if (codePoint === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
(codePoint >= 97 && codePoint <= 122) || // 'a' to 'z'
|
||||
(codePoint >= 65 && codePoint <= 90) || // 'A' to 'Z'
|
||||
codePoint === 95 || // '_'
|
||||
codePoint === 58 || // ':'
|
||||
(codePoint >= 48 && codePoint <= 57 && index > 0) // '0' to '9', but not at the start
|
||||
);
|
||||
};
|
||||
|
||||
const isValidCodePoint = (codePoint: number): boolean => {
|
||||
// Validate the code point for UTF-8 compliance if needed.
|
||||
return codePoint >= 0 && codePoint <= 0x10ffff;
|
||||
};
|
||||
|
||||
export const wrapUtf8Filters = (filterStr: string): string => {
|
||||
const resultArray: string[] = [];
|
||||
let currentKey = '';
|
||||
let currentValue = '';
|
||||
let inQuotes = false;
|
||||
let temp = '';
|
||||
|
||||
for (const char of filterStr) {
|
||||
if (char === '"' && temp[temp.length - 1] !== '\\') {
|
||||
// Toggle inQuotes when an unescaped quote is found
|
||||
inQuotes = !inQuotes;
|
||||
temp += char;
|
||||
} else if (char === ',' && !inQuotes) {
|
||||
// When outside quotes and encountering ',', finalize the current pair
|
||||
[currentKey, currentValue] = temp.split('=');
|
||||
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
|
||||
temp = ''; // Reset for the next pair
|
||||
} else {
|
||||
// Collect characters
|
||||
temp += char;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the last key-value pair
|
||||
if (temp) {
|
||||
[currentKey, currentValue] = temp.split('=');
|
||||
resultArray.push(`${utf8Support(currentKey.trim())}="${currentValue.slice(1, -1)}"`);
|
||||
}
|
||||
|
||||
return resultArray.join(',');
|
||||
};
|
||||
@@ -58,10 +58,10 @@
|
||||
"@leeoniya/ufuzzy": "1.0.18",
|
||||
"@monaco-editor/react": "4.6.0",
|
||||
"@popperjs/core": "2.11.8",
|
||||
"@react-aria/dialog": "3.5.20",
|
||||
"@react-aria/focus": "3.19.0",
|
||||
"@react-aria/overlays": "3.24.0",
|
||||
"@react-aria/utils": "3.26.0",
|
||||
"@react-aria/dialog": "3.5.21",
|
||||
"@react-aria/focus": "3.19.1",
|
||||
"@react-aria/overlays": "3.25.0",
|
||||
"@react-aria/utils": "3.27.0",
|
||||
"@tanstack/react-virtual": "^3.5.1",
|
||||
"@types/jquery": "3.5.32",
|
||||
"@types/lodash": "4.17.14",
|
||||
@@ -85,8 +85,8 @@
|
||||
"prismjs": "1.29.0",
|
||||
"rc-cascader": "3.33.0",
|
||||
"rc-drawer": "7.2.0",
|
||||
"rc-picker": "4.9.2",
|
||||
"rc-slider": "11.1.8",
|
||||
"rc-time-picker": "^3.7.3",
|
||||
"rc-tooltip": "6.4.0",
|
||||
"react-calendar": "^5.1.0",
|
||||
"react-colorful": "5.6.1",
|
||||
|
||||
+6
-20
@@ -1,4 +1,4 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { render, screen, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { dateTime, dateTimeAsMoment, dateTimeForTimeZone, getTimeZone, setTimeZoneResolver } from '@grafana/data';
|
||||
@@ -86,23 +86,16 @@ describe('Date time picker', () => {
|
||||
|
||||
// open the time of day overlay
|
||||
await userEvent.click(screen.getAllByRole('textbox')[1]);
|
||||
const hourList = screen.getAllByRole('list')[0];
|
||||
|
||||
// change the hour
|
||||
await userEvent.click(
|
||||
screen.getAllByRole('button', {
|
||||
name: '00',
|
||||
})[0]
|
||||
);
|
||||
await userEvent.click(within(hourList).getByText('00'));
|
||||
|
||||
// Check the active day is the 5th
|
||||
expect(screen.getByRole('button', { name: 'May 5, 2021' })).toHaveClass('react-calendar__tile--active');
|
||||
|
||||
// change the hour
|
||||
await userEvent.click(
|
||||
screen.getAllByRole('button', {
|
||||
name: '23',
|
||||
})[0]
|
||||
);
|
||||
await userEvent.click(within(hourList).getByText('23'));
|
||||
|
||||
// Check the active day is the 5th
|
||||
expect(screen.getByRole('button', { name: 'May 5, 2021' })).toHaveClass('react-calendar__tile--active');
|
||||
@@ -123,7 +116,6 @@ describe('Date time picker', () => {
|
||||
await userEvent.click(screen.getByRole('button', { name: 'May 15, 2021' }));
|
||||
|
||||
const timeInput = screen.getAllByRole('textbox')[1];
|
||||
expect(timeInput).toHaveClass('rc-time-picker-input');
|
||||
expect(timeInput).not.toHaveDisplayValue('00:00:00');
|
||||
}
|
||||
);
|
||||
@@ -216,9 +208,7 @@ describe('Date time picker', () => {
|
||||
await userEvent.click(screen.getAllByRole('textbox')[1]);
|
||||
|
||||
// check the hour element is visible
|
||||
const hourElement = screen.getAllByRole('button', {
|
||||
name: '00',
|
||||
})[0];
|
||||
const hourElement = screen.getAllByText('00')[0];
|
||||
expect(hourElement).toBeVisible();
|
||||
|
||||
// select the hour value and check it's still visible
|
||||
@@ -227,11 +217,7 @@ describe('Date time picker', () => {
|
||||
|
||||
// click outside the overlay and check the hour element is no longer visible
|
||||
await userEvent.click(document.body);
|
||||
expect(
|
||||
screen.queryByRole('button', {
|
||||
name: '00',
|
||||
})
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('00')).not.toBeInTheDocument();
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export const Basic: StoryFn<typeof TimeOfDayPicker> = (args) => {
|
||||
return (
|
||||
<TimeOfDayPicker
|
||||
{...args}
|
||||
onChange={(newValue) => {
|
||||
onChange={(newValue?) => {
|
||||
action('on selected')(newValue);
|
||||
updateArgs({ value: newValue });
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { css, cx } from '@emotion/css';
|
||||
import RcTimePicker from 'rc-time-picker';
|
||||
import { Moment } from 'moment';
|
||||
import RcPicker, { PickerProps } from 'rc-picker';
|
||||
import generateConfig from 'rc-picker/lib/generate/moment';
|
||||
import locale from 'rc-picker/lib/locale/en_US';
|
||||
|
||||
import { dateTime, DateTime, dateTimeAsMoment, GrafanaTheme2, isDateTimeInput } from '@grafana/data';
|
||||
|
||||
@@ -8,62 +11,102 @@ import { getFocusStyles } from '../../themes/mixins';
|
||||
import { inputSizes } from '../Forms/commonStyles';
|
||||
import { FormInputSize } from '../Forms/types';
|
||||
import { Icon } from '../Icon/Icon';
|
||||
import 'rc-picker/assets/index.css';
|
||||
|
||||
import 'rc-time-picker/assets/index.css';
|
||||
|
||||
export interface Props {
|
||||
onChange: (value: DateTime) => void;
|
||||
interface BaseProps {
|
||||
onChange: (value: DateTime) => void | ((value?: DateTime) => void);
|
||||
value?: DateTime;
|
||||
showHour?: boolean;
|
||||
showSeconds?: boolean;
|
||||
minuteStep?: number;
|
||||
minuteStep?: PickerProps['minuteStep'];
|
||||
size?: FormInputSize;
|
||||
disabled?: boolean;
|
||||
disabledHours?: () => number[];
|
||||
disabledMinutes?: () => number[];
|
||||
disabledSeconds?: () => number[];
|
||||
placeholder?: string;
|
||||
allowEmpty?: boolean;
|
||||
}
|
||||
|
||||
interface AllowEmptyProps extends BaseProps {
|
||||
allowEmpty: true;
|
||||
onChange: (value?: DateTime) => void;
|
||||
}
|
||||
|
||||
interface NoAllowEmptyProps extends BaseProps {
|
||||
allowEmpty?: false;
|
||||
onChange: (value: DateTime) => void;
|
||||
}
|
||||
|
||||
export type Props = AllowEmptyProps | NoAllowEmptyProps;
|
||||
|
||||
export const POPUP_CLASS_NAME = 'time-of-day-picker-panel';
|
||||
|
||||
export const TimeOfDayPicker = ({
|
||||
minuteStep = 1,
|
||||
showHour = true,
|
||||
showSeconds = false,
|
||||
onChange,
|
||||
value,
|
||||
size = 'auto',
|
||||
disabled,
|
||||
disabledHours,
|
||||
disabledMinutes,
|
||||
disabledSeconds,
|
||||
placeholder,
|
||||
// note: we can't destructure allowEmpty/onChange here
|
||||
// in order to discriminate the types properly later in the onChange handler
|
||||
...restProps
|
||||
}: Props) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
const allowClear = restProps.allowEmpty ?? false;
|
||||
|
||||
return (
|
||||
<RcTimePicker
|
||||
<RcPicker<Moment>
|
||||
generateConfig={generateConfig}
|
||||
locale={locale}
|
||||
allowClear={
|
||||
allowClear && {
|
||||
clearIcon: <Icon name="times" className={styles.clearIcon} />,
|
||||
}
|
||||
}
|
||||
className={cx(inputSizes()[size], styles.input)}
|
||||
popupClassName={cx(styles.picker, POPUP_CLASS_NAME)}
|
||||
defaultValue={dateTimeAsMoment()}
|
||||
classNames={{
|
||||
popup: cx(styles.picker, POPUP_CLASS_NAME),
|
||||
}}
|
||||
defaultValue={restProps.allowEmpty ? undefined : dateTimeAsMoment()}
|
||||
disabled={disabled}
|
||||
disabledTime={() => ({
|
||||
disabledHours,
|
||||
disabledMinutes,
|
||||
disabledSeconds,
|
||||
})}
|
||||
format={generateFormat(showHour, showSeconds)}
|
||||
minuteStep={minuteStep}
|
||||
onChange={(value) => {
|
||||
if (isDateTimeInput(value)) {
|
||||
return onChange(dateTime(value));
|
||||
if (restProps.allowEmpty) {
|
||||
return restProps.onChange(value ? dateTime(value) : undefined);
|
||||
} else {
|
||||
return restProps.onChange(dateTime(value));
|
||||
}
|
||||
}
|
||||
}}
|
||||
allowEmpty={false}
|
||||
showSecond={showSeconds}
|
||||
value={dateTimeAsMoment(value)}
|
||||
showHour={showHour}
|
||||
minuteStep={minuteStep}
|
||||
inputIcon={<Caret wrapperStyle={styles.caretWrapper} />}
|
||||
disabled={disabled}
|
||||
disabledHours={disabledHours}
|
||||
disabledMinutes={disabledMinutes}
|
||||
disabledSeconds={disabledSeconds}
|
||||
picker="time"
|
||||
placeholder={placeholder}
|
||||
showNow={false}
|
||||
needConfirm={false}
|
||||
suffixIcon={<Caret wrapperStyle={styles.caretWrapper} />}
|
||||
value={value ? dateTimeAsMoment(value) : value}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
function generateFormat(showHour = true, showSeconds = false) {
|
||||
const maybeHour = showHour ? 'HH:' : '';
|
||||
const maybeSecond = showSeconds ? ':ss' : '';
|
||||
return maybeHour + 'mm' + maybeSecond;
|
||||
}
|
||||
|
||||
interface CaretProps {
|
||||
wrapperStyle?: string;
|
||||
}
|
||||
@@ -78,31 +121,44 @@ const Caret = ({ wrapperStyle = '' }: CaretProps) => {
|
||||
|
||||
const getStyles = (theme: GrafanaTheme2) => {
|
||||
const bgColor = theme.components.input.background;
|
||||
const menuShadowColor = theme.v1.palette.black;
|
||||
const optionBgHover = theme.colors.background.secondary;
|
||||
const optionBgHover = theme.colors.action.hover;
|
||||
const borderRadius = theme.shape.radius.default;
|
||||
const borderColor = theme.components.input.borderColor;
|
||||
|
||||
return {
|
||||
caretWrapper: css({
|
||||
position: 'absolute',
|
||||
right: '8px',
|
||||
position: 'relative',
|
||||
top: '50%',
|
||||
transform: 'translateY(-50%)',
|
||||
display: 'inline-block',
|
||||
textAlign: 'right',
|
||||
color: theme.colors.text.secondary,
|
||||
}),
|
||||
clearIcon: css({
|
||||
color: theme.colors.text.secondary,
|
||||
|
||||
'&:hover': {
|
||||
color: theme.colors.text.maxContrast,
|
||||
},
|
||||
}),
|
||||
picker: css({
|
||||
'.rc-time-picker-panel-select': {
|
||||
fontSize: '14px',
|
||||
'&.rc-picker-dropdown': {
|
||||
boxShadow: 'none',
|
||||
zIndex: theme.zIndex.portal,
|
||||
},
|
||||
'.rc-picker-time-panel-column': {
|
||||
fontSize: theme.typography.htmlFontSize,
|
||||
backgroundColor: bgColor,
|
||||
color: theme.colors.text.secondary,
|
||||
borderColor,
|
||||
padding: 'unset',
|
||||
overflowY: 'auto',
|
||||
scrollbarWidth: 'thin',
|
||||
width: theme.spacing(8),
|
||||
li: {
|
||||
outlineWidth: '2px',
|
||||
'&.rc-time-picker-panel-select-option-selected': {
|
||||
paddingRight: theme.spacing(2),
|
||||
width: 'auto',
|
||||
'&.rc-picker-time-panel-cell-selected': {
|
||||
backgroundColor: 'inherit',
|
||||
border: `1px solid ${theme.v1.palette.orange}`,
|
||||
border: `1px solid ${theme.colors.action.selectedBorder}`,
|
||||
borderRadius,
|
||||
color: theme.colors.text.primary,
|
||||
},
|
||||
@@ -112,44 +168,37 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
color: theme.colors.text.primary,
|
||||
},
|
||||
|
||||
'&.rc-time-picker-panel-select-option-disabled': {
|
||||
'&.rc-picker-time-panel-cell-disabled': {
|
||||
color: theme.colors.action.disabledText,
|
||||
},
|
||||
},
|
||||
|
||||
'.rc-picker-time-panel-cell-inner': {
|
||||
color: 'inherit',
|
||||
},
|
||||
|
||||
'&:not(:last-of-type)': {
|
||||
borderRight: `1px solid ${borderColor}`,
|
||||
},
|
||||
},
|
||||
|
||||
'.rc-time-picker-panel-inner': {
|
||||
boxShadow: `0px 4px 4px ${menuShadowColor}`,
|
||||
'.rc-picker-panel': {
|
||||
boxShadow: theme.shadows.z3,
|
||||
backgroundColor: bgColor,
|
||||
borderColor,
|
||||
borderRadius,
|
||||
marginTop: '3px',
|
||||
|
||||
'.rc-time-picker-panel-input-wrap': {
|
||||
marginRight: '2px',
|
||||
|
||||
'&, .rc-time-picker-panel-input': {
|
||||
backgroundColor: bgColor,
|
||||
paddingTop: '2px',
|
||||
},
|
||||
},
|
||||
|
||||
'.rc-time-picker-panel-combobox': {
|
||||
display: 'flex',
|
||||
},
|
||||
overflow: 'hidden',
|
||||
},
|
||||
}),
|
||||
input: css({
|
||||
'.rc-time-picker-input': {
|
||||
backgroundColor: bgColor,
|
||||
borderRadius,
|
||||
borderColor,
|
||||
color: theme.colors.text.primary,
|
||||
height: theme.spacing(4),
|
||||
'&.rc-picker-focused': {
|
||||
border: 'none',
|
||||
|
||||
'&:focus': getFocusStyles(theme),
|
||||
'.rc-picker-input': getFocusStyles(theme),
|
||||
},
|
||||
|
||||
'&:disabled': {
|
||||
'&.rc-picker-disabled': {
|
||||
'.rc-picker-input': {
|
||||
backgroundColor: theme.colors.action.disabledBackground,
|
||||
color: theme.colors.action.disabledText,
|
||||
border: `1px solid ${theme.colors.action.disabledBackground}`,
|
||||
@@ -158,6 +207,36 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'.rc-picker-input': {
|
||||
backgroundColor: bgColor,
|
||||
borderRadius,
|
||||
borderColor,
|
||||
borderStyle: 'solid',
|
||||
borderWidth: '1px',
|
||||
color: theme.colors.text.primary,
|
||||
height: theme.spacing(4),
|
||||
padding: theme.spacing(0, 1),
|
||||
|
||||
input: {
|
||||
color: 'unset',
|
||||
backgroundColor: 'unset',
|
||||
'&:focus': {
|
||||
outline: 'none',
|
||||
},
|
||||
|
||||
'&::placeholder': {
|
||||
color: theme.colors.text.disabled,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
'.rc-picker-clear': {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
insetInlineEnd: 'unset',
|
||||
position: 'relative',
|
||||
},
|
||||
}),
|
||||
};
|
||||
};
|
||||
@@ -11,7 +11,7 @@ import type { ReactMonacoEditorProps } from './types';
|
||||
monacoEditorLoader.config({ monaco });
|
||||
|
||||
export const ReactMonacoEditor = (props: ReactMonacoEditorProps) => {
|
||||
const { beforeMount, options, ...restProps } = props;
|
||||
const { beforeMount, onMount, options, ...restProps } = props;
|
||||
|
||||
const theme = useTheme2();
|
||||
const onMonacoBeforeMount = useCallback(
|
||||
@@ -31,6 +31,15 @@ export const ReactMonacoEditor = (props: ReactMonacoEditorProps) => {
|
||||
}}
|
||||
theme={theme.isDark ? 'grafana-dark' : 'grafana-light'}
|
||||
beforeMount={onMonacoBeforeMount}
|
||||
onMount={(editor, monaco) => {
|
||||
// we use a custom font in our monaco editor
|
||||
// we need monaco to remeasure the fonts after they are loaded to prevent alignment issues
|
||||
// see https://github.com/microsoft/monaco-editor/issues/648#issuecomment-564978560
|
||||
document.fonts.ready.then(() => {
|
||||
monaco.editor.remeasureFonts();
|
||||
});
|
||||
onMount?.(editor, monaco);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useState } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { IconSize } from '../../types/icon';
|
||||
@@ -6,7 +6,7 @@ import { IconButton } from '../IconButton/IconButton';
|
||||
import { Stack } from '../Layout/Stack/Stack';
|
||||
import { TooltipPlacement } from '../Tooltip';
|
||||
|
||||
import { TableCellInspector, TableCellInspectorMode } from './TableCellInspector';
|
||||
import { TableCellInspectorMode } from './TableCellInspector';
|
||||
import { FILTER_FOR_OPERATOR, FILTER_OUT_OPERATOR, TableCellProps } from './types';
|
||||
import { getTextAlign } from './utils';
|
||||
|
||||
@@ -20,9 +20,14 @@ interface CommonButtonProps {
|
||||
tooltipPlacement: TooltipPlacement;
|
||||
}
|
||||
|
||||
export function CellActions({ field, cell, previewMode, showFilters, onCellFilterAdded }: CellActionProps) {
|
||||
const [isInspecting, setIsInspecting] = useState(false);
|
||||
|
||||
export function CellActions({
|
||||
field,
|
||||
cell,
|
||||
previewMode,
|
||||
showFilters,
|
||||
onCellFilterAdded,
|
||||
setInspectCell,
|
||||
}: CellActionProps) {
|
||||
const isRightAligned = getTextAlign(field) === 'flex-end';
|
||||
const inspectEnabled = Boolean(field.config.custom?.inspect);
|
||||
const commonButtonProps: CommonButtonProps = {
|
||||
@@ -48,37 +53,27 @@ export function CellActions({ field, cell, previewMode, showFilters, onCellFilte
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`cellActions${isRightAligned ? ' cellActionsLeft' : ''}`}>
|
||||
<Stack gap={0.5}>
|
||||
{inspectEnabled && (
|
||||
<IconButton
|
||||
name="eye"
|
||||
tooltip="Inspect value"
|
||||
onClick={() => {
|
||||
setIsInspecting(true);
|
||||
}}
|
||||
{...commonButtonProps}
|
||||
/>
|
||||
)}
|
||||
{showFilters && (
|
||||
<IconButton name={'search-plus'} onClick={onFilterFor} tooltip="Filter for value" {...commonButtonProps} />
|
||||
)}
|
||||
{showFilters && (
|
||||
<IconButton name={'search-minus'} onClick={onFilterOut} tooltip="Filter out value" {...commonButtonProps} />
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
{isInspecting && (
|
||||
<TableCellInspector
|
||||
mode={previewMode}
|
||||
value={cell.value}
|
||||
onDismiss={() => {
|
||||
setIsInspecting(false);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
<div className={`cellActions${isRightAligned ? ' cellActionsLeft' : ''}`}>
|
||||
<Stack gap={0.5}>
|
||||
{inspectEnabled && (
|
||||
<IconButton
|
||||
name="eye"
|
||||
tooltip="Inspect value"
|
||||
onClick={() => {
|
||||
if (setInspectCell) {
|
||||
setInspectCell({ value: cell.value, mode: previewMode });
|
||||
}
|
||||
}}
|
||||
{...commonButtonProps}
|
||||
/>
|
||||
)}
|
||||
{showFilters && (
|
||||
<IconButton name={'search-plus'} onClick={onFilterFor} tooltip="Filter for value" {...commonButtonProps} />
|
||||
)}
|
||||
{showFilters && (
|
||||
<IconButton name={'search-minus'} onClick={onFilterOut} tooltip="Filter out value" {...commonButtonProps} />
|
||||
)}
|
||||
</Stack>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { cx } from '@emotion/css';
|
||||
import { ReactElement, useState } from 'react';
|
||||
import { ReactElement } from 'react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { DisplayValue, formattedValueToString } from '@grafana/data';
|
||||
@@ -28,18 +28,10 @@ export const DefaultCell = (props: TableCellProps) => {
|
||||
const hasLinks = Boolean(getCellLinks(field, row)?.length);
|
||||
const hasActions = Boolean(actions?.length);
|
||||
const clearButtonStyle = useStyles2(clearLinkButtonStyles);
|
||||
const [hover, setHover] = useState(false);
|
||||
let value: string | ReactElement;
|
||||
|
||||
const OG_TWEET_LENGTH = 140; // 🙏
|
||||
|
||||
const onMouseLeave = () => {
|
||||
setHover(false);
|
||||
};
|
||||
const onMouseEnter = () => {
|
||||
setHover(true);
|
||||
};
|
||||
|
||||
if (cellOptions.type === TableCellDisplayMode.Custom) {
|
||||
const CustomCellComponent: React.ComponentType<CustomCellRendererProps> = cellOptions.cellComponent;
|
||||
value = <CustomCellComponent field={field} value={cell.value} rowIndex={row.index} frame={frame} />;
|
||||
@@ -88,13 +80,7 @@ export const DefaultCell = (props: TableCellProps) => {
|
||||
const { key, ...rest } = cellProps;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={key}
|
||||
{...rest}
|
||||
onMouseEnter={showActions ? onMouseEnter : undefined}
|
||||
onMouseLeave={showActions ? onMouseLeave : undefined}
|
||||
className={cellStyle}
|
||||
>
|
||||
<div key={key} {...rest} className={cellStyle}>
|
||||
{hasLinks || hasActions ? (
|
||||
<DataLinksContextMenu links={() => getCellLinks(field, row) || []} actions={actions}>
|
||||
{(api) => {
|
||||
@@ -118,9 +104,7 @@ export const DefaultCell = (props: TableCellProps) => {
|
||||
<div className={tableStyles.cellText}>{value}</div>
|
||||
)}
|
||||
|
||||
{hover && showActions && (
|
||||
<CellActions {...props} previewMode={TableCellInspectorMode.text} showFilters={showFilters} />
|
||||
)}
|
||||
{showActions && <CellActions {...props} previewMode={TableCellInspectorMode.text} showFilters={showFilters} />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,7 +24,13 @@ import { usePanelContext } from '../PanelChrome';
|
||||
import { ExpandedRow, getExpandedRowHeight } from './ExpandedRow';
|
||||
import { TableCell } from './TableCell';
|
||||
import { TableStyles } from './styles';
|
||||
import { CellColors, GetActionsFunction, TableFieldOptions, TableFilterActionCallback } from './types';
|
||||
import {
|
||||
CellColors,
|
||||
GetActionsFunction,
|
||||
TableFieldOptions,
|
||||
TableFilterActionCallback,
|
||||
TableInspectCellCallback,
|
||||
} from './types';
|
||||
import {
|
||||
calculateAroundPointThreshold,
|
||||
getCellColors,
|
||||
@@ -57,6 +63,7 @@ interface RowsListProps {
|
||||
textWrapField?: Field;
|
||||
getActions?: GetActionsFunction;
|
||||
replaceVariables?: InterpolateFunction;
|
||||
setInspectCell?: TableInspectCellCallback;
|
||||
}
|
||||
|
||||
export const RowsList = (props: RowsListProps) => {
|
||||
@@ -85,6 +92,7 @@ export const RowsList = (props: RowsListProps) => {
|
||||
textWrapField,
|
||||
getActions,
|
||||
replaceVariables,
|
||||
setInspectCell,
|
||||
} = props;
|
||||
|
||||
const [rowHighlightIndex, setRowHighlightIndex] = useState<number | undefined>(initialRowIndex);
|
||||
@@ -346,6 +354,7 @@ export const RowsList = (props: RowsListProps) => {
|
||||
height={Number(style.height)}
|
||||
getActions={getActions}
|
||||
replaceVariables={replaceVariables}
|
||||
setInspectCell={setInspectCell}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -374,6 +383,7 @@ export const RowsList = (props: RowsListProps) => {
|
||||
timeRange,
|
||||
getActions,
|
||||
replaceVariables,
|
||||
setInspectCell,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -22,10 +22,11 @@ import { Pagination } from '../Pagination/Pagination';
|
||||
import { FooterRow } from './FooterRow';
|
||||
import { HeaderRow } from './HeaderRow';
|
||||
import { RowsList } from './RowsList';
|
||||
import { TableCellInspector } from './TableCellInspector';
|
||||
import { useFixScrollbarContainer, useResetVariableListSizeCache } from './hooks';
|
||||
import { getInitialState, useTableStateReducer } from './reducer';
|
||||
import { useTableStyles } from './styles';
|
||||
import { FooterItem, GrafanaTableState, Props } from './types';
|
||||
import { FooterItem, GrafanaTableState, InspectCell, Props } from './types';
|
||||
import {
|
||||
getColumns,
|
||||
sortCaseInsensitive,
|
||||
@@ -72,6 +73,7 @@ export const Table = memo((props: Props) => {
|
||||
const headerHeight = noHeader ? 0 : tableStyles.rowHeight;
|
||||
const [footerItems, setFooterItems] = useState<FooterItem[] | undefined>(footerValues);
|
||||
const noValuesDisplayText = fieldConfig?.defaults?.noValue ?? NO_DATA_TEXT;
|
||||
const [inspectCell, setInspectCell] = useState<InspectCell | null>(null);
|
||||
|
||||
const footerHeight = useMemo(() => {
|
||||
const EXTENDED_ROW_HEIGHT = FOOTER_ROW_HEIGHT;
|
||||
@@ -324,66 +326,82 @@ export const Table = memo((props: Props) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
{...getTableProps()}
|
||||
className={tableStyles.table}
|
||||
aria-label={ariaLabel}
|
||||
role="table"
|
||||
ref={tableDivRef}
|
||||
style={{ width, height }}
|
||||
>
|
||||
<CustomScrollbar hideVerticalTrack={true}>
|
||||
<div className={tableStyles.tableContentWrapper(totalColumnsWidth)}>
|
||||
{!noHeader && (
|
||||
<HeaderRow headerGroups={headerGroups} showTypeIcons={showTypeIcons} tableStyles={tableStyles} />
|
||||
)}
|
||||
{itemCount > 0 ? (
|
||||
<div data-testid={selectors.components.Panels.Visualization.Table.body} ref={variableSizeListScrollbarRef}>
|
||||
<RowsList
|
||||
headerGroups={headerGroups}
|
||||
data={data}
|
||||
rows={rows}
|
||||
width={width}
|
||||
cellHeight={cellHeight}
|
||||
headerHeight={headerHeight}
|
||||
rowHeight={tableStyles.rowHeight}
|
||||
itemCount={itemCount}
|
||||
pageIndex={state.pageIndex}
|
||||
listHeight={listHeight}
|
||||
listRef={listRef}
|
||||
tableState={state}
|
||||
prepareRow={prepareRow}
|
||||
timeRange={timeRange}
|
||||
onCellFilterAdded={onCellFilterAdded}
|
||||
nestedDataField={nestedDataField}
|
||||
<>
|
||||
<div
|
||||
{...getTableProps()}
|
||||
className={tableStyles.table}
|
||||
aria-label={ariaLabel}
|
||||
role="table"
|
||||
ref={tableDivRef}
|
||||
style={{ width, height }}
|
||||
>
|
||||
<CustomScrollbar hideVerticalTrack={true}>
|
||||
<div className={tableStyles.tableContentWrapper(totalColumnsWidth)}>
|
||||
{!noHeader && (
|
||||
<HeaderRow headerGroups={headerGroups} showTypeIcons={showTypeIcons} tableStyles={tableStyles} />
|
||||
)}
|
||||
{itemCount > 0 ? (
|
||||
<div
|
||||
data-testid={selectors.components.Panels.Visualization.Table.body}
|
||||
ref={variableSizeListScrollbarRef}
|
||||
>
|
||||
<RowsList
|
||||
headerGroups={headerGroups}
|
||||
data={data}
|
||||
rows={rows}
|
||||
width={width}
|
||||
cellHeight={cellHeight}
|
||||
headerHeight={headerHeight}
|
||||
rowHeight={tableStyles.rowHeight}
|
||||
itemCount={itemCount}
|
||||
pageIndex={state.pageIndex}
|
||||
listHeight={listHeight}
|
||||
listRef={listRef}
|
||||
tableState={state}
|
||||
prepareRow={prepareRow}
|
||||
timeRange={timeRange}
|
||||
onCellFilterAdded={onCellFilterAdded}
|
||||
nestedDataField={nestedDataField}
|
||||
tableStyles={tableStyles}
|
||||
footerPaginationEnabled={Boolean(enablePagination)}
|
||||
enableSharedCrosshair={enableSharedCrosshair}
|
||||
initialRowIndex={initialRowIndex}
|
||||
longestField={longestField}
|
||||
textWrapField={textWrapField}
|
||||
getActions={getActions}
|
||||
replaceVariables={replaceVariables}
|
||||
setInspectCell={setInspectCell}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ height: height - headerHeight, width }} className={tableStyles.noData}>
|
||||
{noValuesDisplayText}
|
||||
</div>
|
||||
)}
|
||||
{footerItems && (
|
||||
<FooterRow
|
||||
isPaginationVisible={Boolean(enablePagination)}
|
||||
footerValues={footerItems}
|
||||
footerGroups={footerGroups}
|
||||
totalColumnsWidth={totalColumnsWidth}
|
||||
tableStyles={tableStyles}
|
||||
footerPaginationEnabled={Boolean(enablePagination)}
|
||||
enableSharedCrosshair={enableSharedCrosshair}
|
||||
initialRowIndex={initialRowIndex}
|
||||
longestField={longestField}
|
||||
textWrapField={textWrapField}
|
||||
getActions={getActions}
|
||||
replaceVariables={replaceVariables}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ height: height - headerHeight, width }} className={tableStyles.noData}>
|
||||
{noValuesDisplayText}
|
||||
</div>
|
||||
)}
|
||||
{footerItems && (
|
||||
<FooterRow
|
||||
isPaginationVisible={Boolean(enablePagination)}
|
||||
footerValues={footerItems}
|
||||
footerGroups={footerGroups}
|
||||
totalColumnsWidth={totalColumnsWidth}
|
||||
tableStyles={tableStyles}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</CustomScrollbar>
|
||||
{paginationEl}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</CustomScrollbar>
|
||||
{paginationEl}
|
||||
</div>
|
||||
|
||||
{inspectCell !== null && (
|
||||
<TableCellInspector
|
||||
mode={inspectCell.mode}
|
||||
value={inspectCell.value}
|
||||
onDismiss={() => {
|
||||
setInspectCell(null);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Cell } from 'react-table';
|
||||
import { TimeRange, DataFrame, InterpolateFunction } from '@grafana/data';
|
||||
|
||||
import { TableStyles } from './styles';
|
||||
import { GetActionsFunction, GrafanaTableColumn, TableFilterActionCallback } from './types';
|
||||
import { GetActionsFunction, GrafanaTableColumn, TableFilterActionCallback, TableInspectCellCallback } from './types';
|
||||
|
||||
export interface Props {
|
||||
cell: Cell;
|
||||
@@ -20,6 +20,7 @@ export interface Props {
|
||||
height?: number;
|
||||
getActions?: GetActionsFunction;
|
||||
replaceVariables?: InterpolateFunction;
|
||||
setInspectCell?: TableInspectCellCallback;
|
||||
}
|
||||
|
||||
export const TableCell = ({
|
||||
@@ -35,6 +36,7 @@ export const TableCell = ({
|
||||
height,
|
||||
getActions,
|
||||
replaceVariables,
|
||||
setInspectCell,
|
||||
}: Props) => {
|
||||
const cellProps = cell.getCellProps();
|
||||
const field = (cell.column as unknown as GrafanaTableColumn).field;
|
||||
@@ -78,6 +80,7 @@ export const TableCell = ({
|
||||
textWrapped,
|
||||
height,
|
||||
actions,
|
||||
setInspectCell,
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from '@grafana/data';
|
||||
import * as schema from '@grafana/schema';
|
||||
|
||||
import { TableCellInspectorMode } from './TableCellInspector';
|
||||
import { TableStyles } from './styles';
|
||||
|
||||
export {
|
||||
@@ -33,6 +34,8 @@ export interface TableRow {
|
||||
[x: string]: any;
|
||||
}
|
||||
|
||||
export type InspectCell = { value: any; mode: TableCellInspectorMode };
|
||||
|
||||
export const FILTER_FOR_OPERATOR = '=';
|
||||
export const FILTER_OUT_OPERATOR = '!=';
|
||||
export type AdHocFilterOperator = typeof FILTER_FOR_OPERATOR | typeof FILTER_OUT_OPERATOR;
|
||||
@@ -40,6 +43,7 @@ export type AdHocFilterItem = { key: string; value: string; operator: AdHocFilte
|
||||
export type TableFilterActionCallback = (item: AdHocFilterItem) => void;
|
||||
export type TableColumnResizeActionCallback = (fieldDisplayName: string, width: number) => void;
|
||||
export type TableSortByActionCallback = (state: TableSortByFieldState[]) => void;
|
||||
export type TableInspectCellCallback = (state: InspectCell) => void;
|
||||
|
||||
export interface TableSortByFieldState {
|
||||
displayName: string;
|
||||
@@ -54,6 +58,7 @@ export interface TableCellProps extends CellProps<any> {
|
||||
innerWidth: number;
|
||||
frame: DataFrame;
|
||||
actions?: ActionModel[];
|
||||
setInspectCell?: TableInspectCellCallback;
|
||||
}
|
||||
|
||||
export type CellComponent = FC<TableCellProps>;
|
||||
|
||||
@@ -19,7 +19,6 @@ import { getLegacySelectStyles } from './legacySelect';
|
||||
import { getMarkdownStyles } from './markdownStyles';
|
||||
import { getPageStyles } from './page';
|
||||
import { getQueryEditorStyles } from './queryEditor';
|
||||
import { getRcTimePickerStyles } from './rcTimePicker';
|
||||
import { getSkeletonStyles } from './skeletonStyles';
|
||||
import { getSlateStyles } from './slate';
|
||||
import { getUplotStyles } from './uPlot';
|
||||
@@ -48,7 +47,6 @@ export function GlobalStyles() {
|
||||
getMarkdownStyles(theme),
|
||||
getPageStyles(theme),
|
||||
getQueryEditorStyles(theme),
|
||||
getRcTimePickerStyles(theme),
|
||||
getSkeletonStyles(theme),
|
||||
getSlateStyles(theme),
|
||||
getUplotStyles(theme),
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import { css } from '@emotion/react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
|
||||
export function getRcTimePickerStyles(theme: GrafanaTheme2) {
|
||||
return css({
|
||||
'.rc-time-picker-input,.rc-time-picker-panel-input-wrap,.rc-time-picker-panel-inner': {
|
||||
backgroundColor: theme.components.input.background,
|
||||
color: theme.colors.text.secondary,
|
||||
borderColor: theme.components.input.borderColor,
|
||||
fontSize: theme.typography.body.fontSize,
|
||||
},
|
||||
|
||||
'.rc-time-picker-input': {
|
||||
padding: theme.spacing(0, 1),
|
||||
height: theme.spacing(4),
|
||||
},
|
||||
|
||||
'.rc-time-picker-panel': {
|
||||
width: '176px',
|
||||
},
|
||||
|
||||
'.rc-time-picker-panel-select': {
|
||||
width: '50%',
|
||||
|
||||
'&:only-child': {
|
||||
width: '100%',
|
||||
},
|
||||
|
||||
'.rc-time-picker-panel-select-option-selected': {
|
||||
backgroundColor: theme.colors.background.secondary,
|
||||
},
|
||||
|
||||
'li:hover': {
|
||||
backgroundColor: theme.colors.background.secondary,
|
||||
},
|
||||
},
|
||||
|
||||
'.rc-time-picker-panel-narrow': {
|
||||
maxWidth: 'none',
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -54,7 +54,7 @@ require (
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.22.0 // indirect
|
||||
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
|
||||
@@ -69,7 +69,7 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.2 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
@@ -128,7 +128,7 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
@@ -144,7 +144,7 @@ require (
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
|
||||
@@ -110,8 +110,8 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g=
|
||||
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40=
|
||||
github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
@@ -154,8 +154,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog=
|
||||
@@ -379,8 +379,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -481,8 +481,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
|
||||
@@ -46,7 +46,7 @@ require (
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@@ -75,7 +75,7 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/net v0.34.0 // indirect
|
||||
@@ -86,7 +86,7 @@ require (
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
|
||||
@@ -89,8 +89,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
@@ -216,8 +216,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -298,8 +298,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
|
||||
+3
-3
@@ -77,7 +77,7 @@ require (
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect; @grafana/grafana-backend-group
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
@@ -92,7 +92,7 @@ require (
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
@@ -106,7 +106,7 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.4.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/log v0.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
)
|
||||
|
||||
+6
-6
@@ -146,8 +146,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKG
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
||||
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
@@ -259,8 +259,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4Jjx
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -343,8 +343,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder/foldertest"
|
||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||
"github.com/grafana/grafana/pkg/services/stats/statsimpl"
|
||||
@@ -28,7 +29,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
func TestConcurrentUsersMetrics(t *testing.T) {
|
||||
sqlStore, cfg := db.InitTestDBWithCfg(t)
|
||||
statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{})
|
||||
statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{}, featuremgmt.WithFeatures())
|
||||
s := createService(t, cfg, sqlStore, statsService)
|
||||
|
||||
createConcurrentTokens(t, sqlStore)
|
||||
@@ -46,7 +47,7 @@ func TestConcurrentUsersMetrics(t *testing.T) {
|
||||
|
||||
func TestConcurrentUsersStats(t *testing.T) {
|
||||
sqlStore, cfg := db.InitTestDBWithCfg(t)
|
||||
statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{})
|
||||
statsService := statsimpl.ProvideService(&setting.Cfg{}, sqlStore, &dashboards.FakeDashboardService{}, &foldertest.FakeService{}, &orgtest.FakeOrgService{}, featuremgmt.WithFeatures())
|
||||
s := createService(t, cfg, sqlStore, statsService)
|
||||
|
||||
createConcurrentTokens(t, sqlStore)
|
||||
|
||||
+3
-3
@@ -53,7 +53,7 @@ require (
|
||||
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.2 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
@@ -100,7 +100,7 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
@@ -112,7 +112,7 @@ require (
|
||||
golang.org/x/tools v0.29.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
google.golang.org/api v0.216.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/grpc v1.69.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
|
||||
+6
-6
@@ -132,8 +132,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpS
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 h1:kQ0NI7W1B3HwiN5gAYtY+XFItDPbLBwYRxAqbFTyDes=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0/go.mod h1:zrT2dxOAjNFPRGjTUe2Xmb4q4YdUwVvQFV6xiCSf+z0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog=
|
||||
@@ -318,8 +318,8 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -386,8 +386,8 @@ gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0=
|
||||
gonum.org/v1/gonum v0.15.1/go.mod h1:eZTZuRFrzu5pcyjN5wJhcIhnUdNijYxX1T2IcrOGY0o=
|
||||
google.golang.org/api v0.216.0 h1:xnEHy+xWFrtYInWPy8OdGFsyIfWJjtVnO39g7pz2BFY=
|
||||
google.golang.org/api v0.216.0/go.mod h1:K9wzQMvWi47Z9IU7OgdOofvZuw75Ge3PPITImZR/UyI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||
|
||||
@@ -4,10 +4,15 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
)
|
||||
|
||||
func init() {
|
||||
model.NameValidationScheme = model.UTF8Validation
|
||||
}
|
||||
|
||||
// ApplyFiltersAndGroupBy takes a raw promQL expression, converts the filters into PromQL matchers, and applies these matchers to the parsed expression. It also applies the group by clause to any aggregate expressions in the parsed expression.
|
||||
func ApplyFiltersAndGroupBy(rawExpr string, scopeFilters, adHocFilters []ScopeFilter, groupBy []string) (string, error) {
|
||||
expr, err := parser.ParseExpr(rawExpr)
|
||||
|
||||
@@ -145,6 +145,37 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyQueryFiltersAndGroupBy_Filters_utf8(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
adhocFilters []ScopeFilter
|
||||
scopeFilters []ScopeFilter
|
||||
expected string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "No filters with existing utf8 filter",
|
||||
query: `http_requests_total{"job.name"="prometheus"}`,
|
||||
expected: `http_requests_total{"job.name"="prometheus"}`,
|
||||
expectErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
expr, err := ApplyFiltersAndGroupBy(tt.query, tt.scopeFilters, tt.adhocFilters, nil)
|
||||
|
||||
if tt.expectErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expected, expr, tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyQueryFiltersAndGroupBy_GroupBy(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -197,7 +228,45 @@ func TestApplyQueryFiltersAndGroupBy_GroupBy(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expr, tt.expected)
|
||||
require.Equal(t, tt.expected, expr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyQueryFiltersAndGroupBy_GroupBy_utf8(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
groupBy []string
|
||||
expected string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "GroupBy with no aggregate expression and utf8 metric",
|
||||
groupBy: []string{"job"},
|
||||
query: `{"http.requests_total"}`,
|
||||
expected: `{__name__="http.requests_total"}`,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "GroupBy with aggregate expression with existing utf8 group by",
|
||||
groupBy: []string{"status"},
|
||||
query: `sum by ("utf8.job") (http_requests_total)`,
|
||||
expected: `sum by ("utf8.job", status) (http_requests_total)`,
|
||||
expectErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
expr, err := ApplyFiltersAndGroupBy(tt.query, nil, nil, tt.groupBy)
|
||||
|
||||
if tt.expectErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expected, expr)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -237,7 +306,72 @@ func TestApplyQueryFiltersAndGroupBy(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expr, tt.expected)
|
||||
require.Equal(t, tt.expected, expr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyQueryFiltersAndGroupBy_utf8(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
query string
|
||||
adhocFilters []ScopeFilter
|
||||
scopeFilters []ScopeFilter
|
||||
groupby []string
|
||||
expected string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
name: "Adhoc filters with more complex expression and utf8 metric name",
|
||||
query: `sum({"capacity_bytes", job="prometheus"} + {"available_bytes", job="grafana"}) / 1024`,
|
||||
adhocFilters: []ScopeFilter{
|
||||
{Key: "job", Value: "alloy", Operator: FilterOperatorEquals},
|
||||
},
|
||||
scopeFilters: []ScopeFilter{
|
||||
{Key: "vol", Value: "/", Operator: FilterOperatorEquals},
|
||||
},
|
||||
groupby: []string{"job"},
|
||||
expected: `sum by (job) ({__name__="capacity_bytes",job="alloy",vol="/"} + {__name__="available_bytes",job="alloy",vol="/"}) / 1024`,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "Adhoc filters with more complex expression with utf8 label",
|
||||
query: `sum(capacity_bytes{job="prometheus", "utf8.label"="value"} + available_bytes{job="grafana"}) / 1024`,
|
||||
adhocFilters: []ScopeFilter{
|
||||
{Key: "job", Value: "alloy", Operator: FilterOperatorEquals},
|
||||
},
|
||||
scopeFilters: []ScopeFilter{
|
||||
{Key: "vol", Value: "/", Operator: FilterOperatorEquals},
|
||||
},
|
||||
groupby: []string{"job"},
|
||||
expected: `sum by (job) (capacity_bytes{"utf8.label"="value",job="alloy",vol="/"} + available_bytes{job="alloy",vol="/"}) / 1024`,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "Adhoc filters with more complex expression with utf8 metric and label",
|
||||
query: `sum({"capacity_bytes", job="prometheus", "utf8.label"="value"} + available_bytes{job="grafana"}) / 1024`,
|
||||
adhocFilters: []ScopeFilter{
|
||||
{Key: "job", Value: "alloy", Operator: FilterOperatorEquals},
|
||||
},
|
||||
scopeFilters: []ScopeFilter{
|
||||
{Key: "vol", Value: "/", Operator: FilterOperatorEquals},
|
||||
},
|
||||
groupby: []string{"job"},
|
||||
expected: `sum by (job) ({"utf8.label"="value",__name__="capacity_bytes",job="alloy",vol="/"} + available_bytes{job="alloy",vol="/"}) / 1024`,
|
||||
expectErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
expr, err := ApplyFiltersAndGroupBy(tt.query, tt.scopeFilters, tt.adhocFilters, tt.groupby)
|
||||
|
||||
if tt.expectErr {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expected, expr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
@@ -340,5 +341,35 @@ func (a *dashboardSqlAccess) CountRepositoryObjects(context.Context, *resource.C
|
||||
|
||||
// GetStats implements ResourceServer.
|
||||
func (a *dashboardSqlAccess) GetStats(ctx context.Context, req *resource.ResourceStatsRequest) (*resource.ResourceStatsResponse, error) {
|
||||
return nil, fmt.Errorf("not yet (GetStats)")
|
||||
info, err := claims.ParseNamespace(req.Namespace)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to read namespace")
|
||||
}
|
||||
if info.OrgID == 0 {
|
||||
return nil, fmt.Errorf("invalid OrgID found in namespace")
|
||||
}
|
||||
|
||||
if len(req.Kinds) != 1 {
|
||||
return nil, fmt.Errorf("only can query for dashboard kind in legacy fallback")
|
||||
}
|
||||
|
||||
parts := strings.SplitN(req.Kinds[0], "/", 2)
|
||||
if len(parts) != 2 {
|
||||
return nil, fmt.Errorf("invalid kind")
|
||||
}
|
||||
|
||||
count, err := a.dashStore.CountInOrg(ctx, info.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &resource.ResourceStatsResponse{
|
||||
Stats: []*resource.ResourceStatsResponse_Stats{
|
||||
{
|
||||
Group: parts[0],
|
||||
Resource: parts[1],
|
||||
Count: count,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package folders
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -80,10 +79,7 @@ func UnstructuredToLegacyFolder(item unstructured.Unstructured, orgID int64) (*f
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
id, err := getLegacyID(meta)
|
||||
if err != nil {
|
||||
return nil, ""
|
||||
}
|
||||
id := meta.GetDeprecatedInternalID() // nolint:staticcheck
|
||||
|
||||
created, err := getCreated(meta)
|
||||
if err != nil {
|
||||
@@ -161,6 +157,8 @@ func convertToK8sResource(v *folder.Folder, namespacer request.NamespaceMapper)
|
||||
|
||||
meta.SetUpdatedTimestamp(&v.Updated)
|
||||
if v.ID > 0 { // nolint:staticcheck
|
||||
meta.SetDeprecatedInternalID(v.ID) // nolint:staticcheck
|
||||
|
||||
meta.SetRepositoryInfo(&utils.ResourceRepositoryInfo{
|
||||
Name: "SQL",
|
||||
Path: fmt.Sprintf("%d", v.ID), // nolint:staticcheck
|
||||
@@ -201,23 +199,6 @@ func setParentUID(u *unstructured.Unstructured, parentUid string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getLegacyID(meta utils.GrafanaMetaAccessor) (int64, error) {
|
||||
var i int64
|
||||
|
||||
repo, err := meta.GetRepositoryInfo()
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
if repo != nil && repo.Name == "SQL" {
|
||||
i, err = strconv.ParseInt(repo.Path, 10, 64)
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func getURL(meta utils.GrafanaMetaAccessor, title string) string {
|
||||
slug := slugify.Slugify(title)
|
||||
uid := meta.GetName()
|
||||
|
||||
@@ -18,13 +18,11 @@ import (
|
||||
common "k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
|
||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
|
||||
grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic"
|
||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/builder"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
@@ -32,6 +30,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/apistore"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
)
|
||||
|
||||
var _ builder.APIGroupBuilder = (*FolderAPIBuilder)(nil)
|
||||
@@ -134,6 +134,9 @@ func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.API
|
||||
cfg: b.cfg,
|
||||
}
|
||||
|
||||
opts.StorageOptions(resourceInfo.GroupResource(), apistore.StorageOptions{
|
||||
RequireDeprecatedInternalID: true})
|
||||
|
||||
storage := map[string]rest.Storage{}
|
||||
storage[resourceInfo.StoragePath()] = legacyStore
|
||||
if optsGetter != nil && dualWriteBuilder != nil {
|
||||
|
||||
@@ -36,6 +36,7 @@ type DashboardService interface {
|
||||
RestoreDashboard(ctx context.Context, dashboard *Dashboard, user identity.Requester, optionalFolderUID string) error
|
||||
CleanUpDeletedDashboards(ctx context.Context) (int64, error)
|
||||
GetSoftDeletedDashboard(ctx context.Context, orgID int64, uid string) (*Dashboard, error)
|
||||
CountDashboardsInOrg(ctx context.Context, orgID int64) (int64, error)
|
||||
}
|
||||
|
||||
// PluginService is a service for operating on plugin dashboards.
|
||||
@@ -82,6 +83,7 @@ type Store interface {
|
||||
ValidateDashboardBeforeSave(ctx context.Context, dashboard *Dashboard, overwrite bool) (bool, error)
|
||||
|
||||
Count(context.Context, *quota.ScopeParameters) (*quota.Map, error)
|
||||
CountInOrg(ctx context.Context, orgID int64) (int64, error)
|
||||
// CountDashboardsInFolder returns the number of dashboards associated with
|
||||
// the given parent folder ID.
|
||||
CountDashboardsInFolders(ctx context.Context, request *CountDashboardsInFolderRequest) (int64, error)
|
||||
|
||||
@@ -168,6 +168,36 @@ func (_m *FakeDashboardService) FindDashboards(ctx context.Context, query *FindP
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// CountDashboardsInOrg provides a mock function with given fields: ctx, orgID
|
||||
func (_m *FakeDashboardService) CountDashboardsInOrg(ctx context.Context, orgID int64) (int64, error) {
|
||||
ret := _m.Called(ctx, orgID)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for CountDashboardsInOrg")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) (int64, error)); ok {
|
||||
return rf(ctx, orgID)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) int64); ok {
|
||||
r0 = rf(ctx, orgID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
|
||||
r1 = rf(ctx, orgID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetAllDashboards provides a mock function with given fields: ctx
|
||||
func (_m *FakeDashboardService) GetAllDashboards(ctx context.Context) ([]*Dashboard, error) {
|
||||
ret := _m.Called(ctx)
|
||||
|
||||
@@ -266,6 +266,24 @@ func (d *dashboardStore) Count(ctx context.Context, scopeParams *quota.ScopePara
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (d *dashboardStore) CountInOrg(ctx context.Context, orgID int64) (int64, error) {
|
||||
type result struct {
|
||||
Count int64
|
||||
}
|
||||
r := result{}
|
||||
if err := d.store.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
rawSQL := fmt.Sprintf("SELECT COUNT(*) AS count FROM dashboard WHERE org_id=? AND is_folder=%s", d.store.GetDialect().BooleanStr(false))
|
||||
if _, err := sess.SQL(rawSQL, orgID).Get(&r); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return r.Count, nil
|
||||
}
|
||||
|
||||
func getExistingDashboardByIDOrUIDForUpdate(sess *db.Session, dash *dashboards.Dashboard, overwrite bool) (bool, error) {
|
||||
dashWithIdExists := false
|
||||
isParentFolderChanged := false
|
||||
|
||||
@@ -61,6 +61,7 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
|
||||
savedDash = insertTestDashboard(t, dashboardStore, "test dash 23", 1, savedFolder.ID, savedFolder.UID, false, "prod", "webapp")
|
||||
insertTestDashboard(t, dashboardStore, "test dash 45", 1, savedFolder.ID, savedFolder.UID, false, "prod")
|
||||
savedDash2 = insertTestDashboard(t, dashboardStore, "test dash 67", 1, 0, "", false, "prod")
|
||||
insertTestDashboard(t, dashboardStore, "test dash org2", 2, 0, "", false, "")
|
||||
insertTestRule(t, sqlStore, savedFolder.OrgID, savedFolder.UID)
|
||||
}
|
||||
|
||||
@@ -81,6 +82,17 @@ func TestIntegrationDashboardDataAccess(t *testing.T) {
|
||||
require.Positive(t, len(savedFolder.UID))
|
||||
})
|
||||
|
||||
t.Run("Should be able to get dashboard counts per org", func(t *testing.T) {
|
||||
setup()
|
||||
count, err := dashboardStore.CountInOrg(context.Background(), 1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(3), count)
|
||||
|
||||
count, err = dashboardStore.CountInOrg(context.Background(), 2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(1), count)
|
||||
})
|
||||
|
||||
t.Run("Should be able to get dashboard by id", func(t *testing.T) {
|
||||
setup()
|
||||
query := dashboards.GetDashboardQuery{
|
||||
|
||||
@@ -52,6 +52,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/search"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
@@ -179,11 +180,10 @@ func (dr *DashboardServiceImpl) Count(ctx context.Context, scopeParams *quota.Sc
|
||||
total := int64(0)
|
||||
for _, org := range orgs {
|
||||
ctx = identity.WithRequester(ctx, getDashboardBackgroundRequester(org.ID))
|
||||
dashs, err := dr.listDashboardsThroughK8s(ctx, org.ID)
|
||||
orgDashboards, err := dr.CountDashboardsInOrg(ctx, org.ID)
|
||||
if err != nil {
|
||||
return u, err
|
||||
return nil, err
|
||||
}
|
||||
orgDashboards := int64(len(dashs))
|
||||
total += orgDashboards
|
||||
|
||||
tag, err := quota.NewTag(dashboards.QuotaTargetSrv, dashboards.QuotaTarget, quota.OrgScope)
|
||||
@@ -205,6 +205,28 @@ func (dr *DashboardServiceImpl) Count(ctx context.Context, scopeParams *quota.Sc
|
||||
return dr.dashboardStore.Count(ctx, scopeParams)
|
||||
}
|
||||
|
||||
func (dr *DashboardServiceImpl) CountDashboardsInOrg(ctx context.Context, orgID int64) (int64, error) {
|
||||
if dr.features.IsEnabledGlobally(featuremgmt.FlagKubernetesCliDashboards) {
|
||||
resp, err := dr.k8sclient.getSearcher().GetStats(ctx, &resource.ResourceStatsRequest{
|
||||
Namespace: dr.k8sclient.getNamespace(orgID),
|
||||
Kinds: []string{
|
||||
v0alpha1.GROUP + "/" + v0alpha1.DashboardResourceInfo.GetName(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(resp.Stats) != 1 {
|
||||
return 0, fmt.Errorf("expected 1 stat, got %d", len(resp.Stats))
|
||||
}
|
||||
|
||||
return resp.Stats[0].Count, nil
|
||||
}
|
||||
|
||||
return dr.dashboardStore.CountInOrg(ctx, orgID)
|
||||
}
|
||||
|
||||
func readQuotaConfig(cfg *setting.Cfg) (*quota.Map, error) {
|
||||
limits := "a.Map{}
|
||||
|
||||
@@ -1215,6 +1237,7 @@ func (dr *DashboardServiceImpl) FindDashboards(ctx context.Context, query *dashb
|
||||
finalResults := make([]dashboards.DashboardSearchProjection, len(response.Hits))
|
||||
for i, hit := range response.Hits {
|
||||
finalResults[i] = dashboards.DashboardSearchProjection{
|
||||
ID: hit.Field.GetNestedInt64(search.DASHBOARD_LEGACY_ID),
|
||||
UID: hit.Name,
|
||||
OrgID: query.OrgId,
|
||||
Title: hit.Title,
|
||||
@@ -1980,7 +2003,7 @@ func ParseResults(result *resource.ResourceSearchResponse, offset int64) (*v0alp
|
||||
for i, row := range result.Results.Rows {
|
||||
fields := &common.Unstructured{}
|
||||
for colIndex, col := range result.Results.Columns {
|
||||
if _, ok := excludedFields[col.Name]; ok {
|
||||
if _, ok := excludedFields[col.Name]; !ok {
|
||||
val, err := resource.DecodeCell(col, colIndex, row.Cells[colIndex])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -271,6 +271,11 @@ func (m *mockResourceIndexClient) Search(ctx context.Context, req *resource.Reso
|
||||
return args.Get(0).(*resource.ResourceSearchResponse), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *mockResourceIndexClient) GetStats(ctx context.Context, in *resource.ResourceStatsRequest, opts ...grpc.CallOption) (*resource.ResourceStatsResponse, error) {
|
||||
args := m.Called(in)
|
||||
return args.Get(0).(*resource.ResourceStatsResponse), args.Error(1)
|
||||
}
|
||||
|
||||
type mockResourceInterface struct {
|
||||
mock.Mock
|
||||
dynamic.ResourceInterface
|
||||
@@ -1779,44 +1784,17 @@ func TestQuotaCount(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
dashboardUnstructuredOrg1 := unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{{
|
||||
Object: map[string]any{
|
||||
"metadata": map[string]any{
|
||||
"name": "uid",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"test": "test",
|
||||
"version": int64(1),
|
||||
"title": "testing slugify",
|
||||
},
|
||||
},
|
||||
}},
|
||||
}
|
||||
dashboardUnstructuredOrg2 := unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{{
|
||||
Object: map[string]any{
|
||||
"metadata": map[string]any{
|
||||
"name": "uid",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"test": "test",
|
||||
"version": int64(1),
|
||||
"title": "testing slugify",
|
||||
},
|
||||
countOrg1 := resource.ResourceStatsResponse{
|
||||
Stats: []*resource.ResourceStatsResponse_Stats{
|
||||
{
|
||||
Count: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
countOrg2 := resource.ResourceStatsResponse{
|
||||
Stats: []*resource.ResourceStatsResponse_Stats{
|
||||
{
|
||||
Object: map[string]any{
|
||||
"metadata": map[string]any{
|
||||
"name": "uid2",
|
||||
},
|
||||
"spec": map[string]any{
|
||||
"test": "test2",
|
||||
"version": int64(1),
|
||||
"title": "testing slugify2",
|
||||
},
|
||||
},
|
||||
Count: 2,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1833,13 +1811,11 @@ func TestQuotaCount(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Should use Kubernetes client if feature flags are enabled", func(t *testing.T) {
|
||||
ctx, k8sClientMock, k8sResourceMock := setupK8sDashboardTests(service)
|
||||
ctx, k8sClientMock, _ := setupK8sDashboardTests(service)
|
||||
orgSvc := orgtest.FakeOrgService{ExpectedOrgs: orgs}
|
||||
service.orgService = &orgSvc
|
||||
k8sClientMock.On("getClient", mock.Anything, int64(1)).Return(k8sResourceMock, true).Once()
|
||||
k8sClientMock.On("getClient", mock.Anything, int64(2)).Return(k8sResourceMock, true).Once()
|
||||
k8sResourceMock.On("List", mock.Anything, mock.Anything).Return(&dashboardUnstructuredOrg2, nil).Once()
|
||||
k8sResourceMock.On("List", mock.Anything, mock.Anything).Return(&dashboardUnstructuredOrg1, nil).Once()
|
||||
k8sClientMock.searcher.On("GetStats", mock.Anything).Return(&countOrg2, nil).Once()
|
||||
k8sClientMock.searcher.On("GetStats", mock.Anything).Return(&countOrg1, nil).Once()
|
||||
|
||||
result, err := service.Count(ctx, query)
|
||||
require.NoError(t, err)
|
||||
@@ -1858,6 +1834,38 @@ func TestQuotaCount(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCountDashboardsInOrg(t *testing.T) {
|
||||
fakeStore := dashboards.FakeDashboardStore{}
|
||||
defer fakeStore.AssertExpectations(t)
|
||||
service := &DashboardServiceImpl{
|
||||
cfg: setting.NewCfg(),
|
||||
dashboardStore: &fakeStore,
|
||||
}
|
||||
count := resource.ResourceStatsResponse{
|
||||
Stats: []*resource.ResourceStatsResponse_Stats{
|
||||
{
|
||||
Count: 3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
t.Run("Should fallback to dashboard store if Kubernetes feature flags are not enabled", func(t *testing.T) {
|
||||
service.features = featuremgmt.WithFeatures()
|
||||
fakeStore.On("CountInOrg", mock.Anything, mock.Anything).Return(nil, nil).Once()
|
||||
_, err := service.CountDashboardsInOrg(context.Background(), 1)
|
||||
require.NoError(t, err)
|
||||
fakeStore.AssertExpectations(t)
|
||||
})
|
||||
|
||||
t.Run("Should use Kubernetes client if feature flags are enabled", func(t *testing.T) {
|
||||
ctx, k8sClientMock, _ := setupK8sDashboardTests(service)
|
||||
k8sClientMock.searcher.On("GetStats", mock.Anything).Return(&count, nil).Once()
|
||||
result, err := service.CountDashboardsInOrg(ctx, 1)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, result, int64(3))
|
||||
})
|
||||
}
|
||||
|
||||
func TestLegacySaveCommandToUnstructured(t *testing.T) {
|
||||
namespace := "test-namespace"
|
||||
t.Run("successfully converts save command to unstructured", func(t *testing.T) {
|
||||
|
||||
@@ -48,6 +48,37 @@ func (_m *FakeDashboardStore) Count(_a0 context.Context, _a1 *quota.ScopeParamet
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// CountInOrg provides a mock function with given fields: _a0, _a1
|
||||
func (_m *FakeDashboardStore) CountInOrg(_a0 context.Context, _a1 int64) (int64, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Count")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) (int64, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, int64) int64); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
|
||||
// CountDashboardsInFolders provides a mock function with given fields: ctx, request
|
||||
func (_m *FakeDashboardStore) CountDashboardsInFolders(ctx context.Context, request *CountDashboardsInFolderRequest) (int64, error) {
|
||||
ret := _m.Called(ctx, request)
|
||||
|
||||
@@ -785,15 +785,6 @@ func TestIntegrationInsertAlertRules(t *testing.T) {
|
||||
require.ErrorIs(t, err, models.ErrAlertRuleFailedValidation)
|
||||
require.ErrorContains(t, err, "metric name for recording rule must be a valid utf8 string")
|
||||
})
|
||||
|
||||
t.Run("invalid metric name", func(t *testing.T) {
|
||||
invalidMetric := "with-dashes"
|
||||
invalidRule := recordingRulesGen.Generate()
|
||||
invalidRule.Record.Metric = invalidMetric
|
||||
_, err := store.InsertAlertRules(context.Background(), []models.AlertRule{invalidRule})
|
||||
require.ErrorIs(t, err, models.ErrAlertRuleFailedValidation)
|
||||
require.ErrorContains(t, err, "metric name for recording rule must be a valid Prometheus metric name")
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("clears fields that should not exist on recording rules", func(t *testing.T) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/libraryelements/model"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
@@ -21,13 +22,14 @@ import (
|
||||
const activeUserTimeLimit = time.Hour * 24 * 30
|
||||
const dailyActiveUserTimeLimit = time.Hour * 24
|
||||
|
||||
func ProvideService(cfg *setting.Cfg, db db.DB, dashSvc dashboards.DashboardService, folderSvc folder.Service, orgSvc org.Service) stats.Service {
|
||||
func ProvideService(cfg *setting.Cfg, db db.DB, dashSvc dashboards.DashboardService, folderSvc folder.Service, orgSvc org.Service, features featuremgmt.FeatureToggles) stats.Service {
|
||||
return &sqlStatsService{
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
folderSvc: folderSvc,
|
||||
dashSvc: dashSvc,
|
||||
orgSvc: orgSvc,
|
||||
features: features,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,48 +37,23 @@ type sqlStatsService struct {
|
||||
db db.DB
|
||||
cfg *setting.Cfg
|
||||
dashSvc dashboards.DashboardService
|
||||
features featuremgmt.FeatureToggles
|
||||
folderSvc folder.Service
|
||||
orgSvc org.Service
|
||||
}
|
||||
|
||||
type dashboardStats struct {
|
||||
count int
|
||||
bytesTotal int
|
||||
bytesMax int
|
||||
}
|
||||
|
||||
func (ss *sqlStatsService) collectDashboardStats(ctx context.Context, orgs []*org.OrgDTO, calculateByteSize bool) (dashboardStats, error) {
|
||||
stats := dashboardStats{
|
||||
count: 0,
|
||||
bytesTotal: 0,
|
||||
bytesMax: 0,
|
||||
}
|
||||
|
||||
func (ss *sqlStatsService) getDashboardCount(ctx context.Context, orgs []*org.OrgDTO) (int64, error) {
|
||||
count := int64(0)
|
||||
for _, org := range orgs {
|
||||
ctx = identity.WithRequester(ctx, getStatsRequester(org.ID))
|
||||
dashs, err := ss.dashSvc.GetAllDashboardsByOrgId(ctx, org.ID)
|
||||
dashsCount, err := ss.dashSvc.CountDashboardsInOrg(ctx, org.ID)
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
stats.count += len(dashs)
|
||||
|
||||
// only calculate bytes if needed
|
||||
if calculateByteSize {
|
||||
for _, dash := range dashs {
|
||||
b, err := dash.Data.ToDB()
|
||||
if err != nil {
|
||||
return stats, err
|
||||
}
|
||||
stats.bytesTotal += len(b)
|
||||
|
||||
if len(b) > stats.bytesMax {
|
||||
stats.bytesMax = len(b)
|
||||
}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
count += dashsCount
|
||||
}
|
||||
|
||||
return stats, nil
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func (ss *sqlStatsService) getTagCount(ctx context.Context, orgs []*org.OrgDTO) (int64, error) {
|
||||
@@ -172,7 +149,6 @@ func (ss *sqlStatsService) GetSystemStats(ctx context.Context, query *stats.GetS
|
||||
monthlyActiveUserDeadlineDate := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
|
||||
sb.Write(`(SELECT COUNT(*) FROM `+dialect.Quote("user")+` WHERE `+
|
||||
notServiceAccount(dialect)+` AND last_seen_at > ?) AS monthly_active_users,`, monthlyActiveUserDeadlineDate)
|
||||
|
||||
sb.Write(`(SELECT COUNT(id) FROM ` + dialect.Quote("dashboard_provisioning") + `) AS provisioned_dashboards,`)
|
||||
sb.Write(`(SELECT COUNT(id) FROM ` + dialect.Quote("dashboard_snapshot") + `) AS snapshots,`)
|
||||
sb.Write(`(SELECT COUNT(id) FROM ` + dialect.Quote("dashboard_version") + `) AS dashboard_versions,`)
|
||||
@@ -190,6 +166,11 @@ func (ss *sqlStatsService) GetSystemStats(ctx context.Context, query *stats.GetS
|
||||
if ss.IsUnifiedAlertingEnabled() {
|
||||
sb.Write(`(SELECT COUNT(DISTINCT (` + dialect.Quote("rule_group") + `)) FROM ` + dialect.Quote("alert_rule") + `) AS rule_groups,`)
|
||||
}
|
||||
// currently not supported when dashboards are in unified storage
|
||||
if !ss.features.IsEnabledGlobally(featuremgmt.FlagKubernetesCliDashboards) {
|
||||
sb.Write(`(SELECT SUM(LENGTH(data)) FROM `+dialect.Quote("dashboard")+` WHERE is_folder = ?) AS dashboard_bytes_total,`, dialect.BooleanStr(false))
|
||||
sb.Write(`(SELECT MAX(LENGTH(data)) FROM `+dialect.Quote("dashboard")+` WHERE is_folder = ?) AS dashboard_bytes_max,`, dialect.BooleanStr(false))
|
||||
}
|
||||
|
||||
sb.Write(ss.roleCounterSQL(ctx))
|
||||
|
||||
@@ -216,13 +197,11 @@ func (ss *sqlStatsService) GetSystemStats(ctx context.Context, query *stats.GetS
|
||||
result.Orgs = int64(len(orgs))
|
||||
|
||||
// for services in unified storage, get the stats through the service rather than the db directly
|
||||
dashStats, err := ss.collectDashboardStats(ctx, orgs, true)
|
||||
dashCount, err := ss.getDashboardCount(ctx, orgs)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.DashboardBytesMax = int64(dashStats.bytesMax)
|
||||
result.DashboardBytesTotal = int64(dashStats.bytesTotal)
|
||||
result.Dashboards = int64(dashStats.count)
|
||||
result.Dashboards = dashCount
|
||||
|
||||
folderCount, err := ss.getFolderCount(ctx, orgs)
|
||||
if err != nil {
|
||||
@@ -329,11 +308,11 @@ func (ss *sqlStatsService) GetAdminStats(ctx context.Context, query *stats.GetAd
|
||||
result.Orgs = int64(len(orgs))
|
||||
|
||||
// for services in unified storage, get the stats through the service rather than the db directly
|
||||
dashStats, err := ss.collectDashboardStats(ctx, orgs, false)
|
||||
dashCount, err := ss.getDashboardCount(ctx, orgs)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.Dashboards = int64(dashStats.count)
|
||||
result.Dashboards = dashCount
|
||||
|
||||
tagCount, err := ss.getTagCount(ctx, orgs)
|
||||
if err != nil {
|
||||
|
||||
@@ -10,12 +10,12 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/services/correlations"
|
||||
"github.com/grafana/grafana/pkg/services/correlations/correlationstest"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/folder"
|
||||
"github.com/grafana/grafana/pkg/services/folder/foldertest"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
@@ -40,15 +40,9 @@ func TestIntegrationStatsDataAccess(t *testing.T) {
|
||||
db, cfg := db.InitTestDBWithCfg(t)
|
||||
orgSvc := populateDB(t, db, cfg)
|
||||
dashSvc := &dashboards.FakeDashboardService{}
|
||||
emptyJson := simplejson.New()
|
||||
emptyJsonBytes, err := emptyJson.ToDB()
|
||||
require.NoError(t, err)
|
||||
largerJson := simplejson.NewFromAny(map[string]string{"key": "value"})
|
||||
largerJsonBytes, err := largerJson.ToDB()
|
||||
require.NoError(t, err)
|
||||
dashSvc.On("GetAllDashboardsByOrgId", mock.Anything, int64(1)).Return([]*dashboards.Dashboard{{Data: largerJson}, {Data: emptyJson}}, nil)
|
||||
dashSvc.On("GetAllDashboardsByOrgId", mock.Anything, int64(2)).Return([]*dashboards.Dashboard{}, nil)
|
||||
dashSvc.On("GetAllDashboardsByOrgId", mock.Anything, int64(3)).Return([]*dashboards.Dashboard{}, nil)
|
||||
dashSvc.On("CountDashboardsInOrg", mock.Anything, int64(1)).Return(int64(2), nil)
|
||||
dashSvc.On("CountDashboardsInOrg", mock.Anything, int64(2)).Return(int64(1), nil)
|
||||
dashSvc.On("CountDashboardsInOrg", mock.Anything, int64(3)).Return(int64(0), nil)
|
||||
dashSvc.On("GetDashboardTags", mock.Anything, &dashboards.GetDashboardTagsQuery{OrgID: 1}).Return([]*dashboards.DashboardTagCloudItem{{Term: "test"}}, nil)
|
||||
dashSvc.On("GetDashboardTags", mock.Anything, &dashboards.GetDashboardTagsQuery{OrgID: 2}).Return([]*dashboards.DashboardTagCloudItem{}, nil)
|
||||
dashSvc.On("GetDashboardTags", mock.Anything, &dashboards.GetDashboardTagsQuery{OrgID: 3}).Return([]*dashboards.DashboardTagCloudItem{}, nil)
|
||||
@@ -61,6 +55,7 @@ func TestIntegrationStatsDataAccess(t *testing.T) {
|
||||
dashSvc: dashSvc,
|
||||
orgSvc: orgSvc,
|
||||
folderSvc: folderService,
|
||||
features: featuremgmt.WithFeatures(),
|
||||
}
|
||||
|
||||
t.Run("Get system stats should not results in error", func(t *testing.T) {
|
||||
@@ -76,10 +71,8 @@ func TestIntegrationStatsDataAccess(t *testing.T) {
|
||||
assert.Equal(t, int64(0), result.APIKeys)
|
||||
assert.Equal(t, int64(2), result.Correlations)
|
||||
assert.Equal(t, int64(3), result.Orgs)
|
||||
assert.Equal(t, int64(2), result.Dashboards)
|
||||
assert.Equal(t, int64(3), result.Dashboards)
|
||||
assert.Equal(t, int64(9), result.Folders) // will return 3 folders for each org
|
||||
assert.Equal(t, int64(len(largerJsonBytes)+len(emptyJsonBytes)), result.DashboardBytesTotal)
|
||||
assert.Equal(t, int64(len(largerJsonBytes)), result.DashboardBytesMax)
|
||||
assert.NotNil(t, result.DatabaseCreatedTime)
|
||||
assert.Equal(t, db.GetDialect().DriverName(), result.DatabaseDriver)
|
||||
})
|
||||
@@ -113,7 +106,7 @@ func TestIntegrationStatsDataAccess(t *testing.T) {
|
||||
stats, err := statsService.GetAdminStats(context.Background(), &query)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(1), stats.Tags)
|
||||
assert.Equal(t, int64(2), stats.Dashboards)
|
||||
assert.Equal(t, int64(3), stats.Dashboards)
|
||||
assert.Equal(t, int64(3), stats.Orgs)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/pkg/storage/unified/apistore
|
||||
|
||||
go 1.23.4
|
||||
go 1.23.5
|
||||
|
||||
replace (
|
||||
github.com/grafana/grafana => ../../../..
|
||||
@@ -55,6 +55,7 @@ require (
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
|
||||
github.com/RoaringBitmap/roaring v1.9.3 // indirect
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f // indirect
|
||||
github.com/Yiling-J/theine-go v0.6.0 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/apache/arrow-go/v18 v18.0.1-0.20241212180703-82be143d7c30 // indirect
|
||||
@@ -115,7 +116,6 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/dlmiddlecote/sqlstats v1.0.2 // indirect
|
||||
github.com/docker/docker v27.4.1+incompatible // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/elazarl/goproxy v1.3.0 // indirect
|
||||
@@ -159,7 +159,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.22.0 // indirect
|
||||
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
|
||||
@@ -185,7 +185,7 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
@@ -203,7 +203,7 @@ require (
|
||||
github.com/invopop/yaml v0.3.1 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.1 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.2 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/jeremywohl/flatten v1.0.1 // indirect
|
||||
github.com/jessevdk/go-flags v1.5.0 // indirect
|
||||
@@ -215,7 +215,6 @@ require (
|
||||
github.com/jpillora/backoff v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/jszwedko/go-datemath v0.1.1-0.20230526204004-640a500621d6 // indirect
|
||||
github.com/karlseguin/ccache/v3 v3.0.5 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
@@ -256,9 +255,9 @@ require (
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/oklog/ulid/v2 v2.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66 // indirect
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f // indirect
|
||||
github.com/openfga/openfga v1.6.2 // indirect
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5 // indirect
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c // indirect
|
||||
github.com/openfga/openfga v1.8.4 // indirect
|
||||
github.com/opentracing-contrib/go-stdlib v1.0.0 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
@@ -268,7 +267,7 @@ require (
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/pressly/goose/v3 v3.22.1 // indirect
|
||||
github.com/pressly/goose/v3 v3.24.0 // indirect
|
||||
github.com/prometheus/alertmanager v0.27.0 // indirect
|
||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
@@ -324,9 +323,9 @@ require (
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
@@ -343,7 +342,7 @@ require (
|
||||
gonum.org/v1/gonum v0.15.1 // indirect
|
||||
google.golang.org/api v0.216.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
@@ -362,7 +361,7 @@ require (
|
||||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.33.1 // indirect
|
||||
modernc.org/sqlite v1.34.4 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect
|
||||
|
||||
@@ -111,6 +111,8 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f h1:HR5nRmUQgXrwqZOwZ2DAc/aCi3Bu3xENpspW935vxu0=
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3HiCrHjHBdcm6E83vGaXh1KomZMA2P6aeo3hKx/wg0=
|
||||
github.com/Yiling-J/theine-go v0.6.0 h1:jv7V/tcD6ijL0T4kfbJDKP81TCZBkoriNTPSqwivWuY=
|
||||
github.com/Yiling-J/theine-go v0.6.0/go.mod h1:mdch1vjgGWd7s3rWKvY+MF5InRLfRv/CWVI9RVNQ8wY=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -473,8 +475,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g=
|
||||
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40=
|
||||
github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
@@ -583,8 +585,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a534
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
@@ -642,8 +644,8 @@ github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5ey
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs=
|
||||
@@ -688,8 +690,6 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karlseguin/ccache/v3 v3.0.5 h1:hFX25+fxzNjsRlREYsoGNa2LoVEw5mPF8wkWq/UnevQ=
|
||||
github.com/karlseguin/ccache/v3 v3.0.5/go.mod h1:qxC372+Qn+IBj8Pe3KvGjHPj0sWwEF7AeZVhsNPZ6uY=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
@@ -831,12 +831,12 @@ github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3I
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66 h1:pAYrdyIKxPsMs/nRcTEnS9za2io11g7Rt7ng7HK82hk=
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66/go.mod h1:gil5LBD8tSdFQbUkCQdnXsoeU9kDJdJgbGdHkgJfcd0=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f h1:ZMZ7ntMnaHIPZxvVQv/aqC4ctzLqH+9Fqn4uw35kQpk=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f/go.mod h1:ll/hN6kS4EE6B/7J/PbZqac9Nuv7ZHpI+Jfh36JLrbs=
|
||||
github.com/openfga/openfga v1.6.2 h1:tHBAgiCPomCZb3IH0CFqOpTDVDA/Xb8kG87oX4JCbXc=
|
||||
github.com/openfga/openfga v1.6.2/go.mod h1:jzbEpheazf6MFjtanQt1rpxexSRzfa9057F7JlkMv2I=
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5 h1:z9jaRoo+NIN1AB0ogjtrjx1316TTuq6IbqpEg3UJycA=
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5/go.mod h1:m74TNgnAAIJ03gfHcx+xaRWnr+IbQy3y/AVNwwCFrC0=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c h1:1y84C0V4NRfPtRi4MqQ7+gnFtYgeBKPIeIAPLdVJ7j4=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c/go.mod h1:12RMe/HuRNyOzS33RQa53jwdcxE2znr8ycXMlVbgQN4=
|
||||
github.com/openfga/openfga v1.8.4 h1:OqyRpuxMCxcS7irTFYFkhAIYzmAnczNwxUqjnuZOQyo=
|
||||
github.com/openfga/openfga v1.8.4/go.mod h1:9Ax9VMMySV2JMsCT8MTePeYt4OrTnPAy1XUV1y9RyuU=
|
||||
github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w=
|
||||
github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
@@ -865,8 +865,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pressly/goose/v3 v3.22.1 h1:2zICEfr1O3yTP9BRZMGPj7qFxQ+ik6yeo+z1LMuioLc=
|
||||
github.com/pressly/goose/v3 v3.22.1/go.mod h1:xtMpbstWyCpyH+0cxLTMCENWBG+0CSxvTsXhW95d5eo=
|
||||
github.com/pressly/goose/v3 v3.24.0 h1:sFbNms7Bd++2VMq6HSgDHDLWa7kHz1qXzPb3ZIU72VU=
|
||||
github.com/pressly/goose/v3 v3.24.0/go.mod h1:rEWreU9uVtt0DHCyLzF9gRcWiiTF/V+528DV+4DORug=
|
||||
github.com/prometheus/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I=
|
||||
github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
@@ -1095,16 +1095,16 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
@@ -1465,8 +1465,8 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
@@ -1586,8 +1586,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM=
|
||||
modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8=
|
||||
modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/pkg/storage/unified/resource
|
||||
|
||||
go 1.23.4
|
||||
go 1.23.5
|
||||
|
||||
replace (
|
||||
github.com/grafana/grafana => ../../../..
|
||||
@@ -127,7 +127,7 @@ require (
|
||||
github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect
|
||||
github.com/grafana/sqlds/v4 v4.1.3 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
@@ -215,7 +215,7 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.33.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect
|
||||
@@ -230,7 +230,7 @@ require (
|
||||
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
|
||||
google.golang.org/api v0.216.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
|
||||
@@ -73,7 +73,8 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f h1:HR5nRmUQgXrwqZOwZ2DAc/aCi3Bu3xENpspW935vxu0=
|
||||
github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3HiCrHjHBdcm6E83vGaXh1KomZMA2P6aeo3hKx/wg0=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||
github.com/Yiling-J/theine-go v0.6.0 h1:jv7V/tcD6ijL0T4kfbJDKP81TCZBkoriNTPSqwivWuY=
|
||||
github.com/Yiling-J/theine-go v0.6.0/go.mod h1:mdch1vjgGWd7s3rWKvY+MF5InRLfRv/CWVI9RVNQ8wY=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -358,8 +359,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g=
|
||||
github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40=
|
||||
github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
|
||||
github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
@@ -442,8 +443,8 @@ github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpS
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0 h1:kQ0NI7W1B3HwiN5gAYtY+XFItDPbLBwYRxAqbFTyDes=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.2.0/go.mod h1:zrT2dxOAjNFPRGjTUe2Xmb4q4YdUwVvQFV6xiCSf+z0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
@@ -495,8 +496,8 @@ github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7Ulw
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx v3.2.0+incompatible h1:0Vihzu20St42/UDsvZGdNE6jak7oi/UOeMzwMPHkgFY=
|
||||
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
|
||||
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jeremywohl/flatten v1.0.1 h1:LrsxmB3hfwJuE+ptGOijix1PIfOoKLJ3Uee/mzbgtrs=
|
||||
@@ -535,8 +536,6 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karlseguin/ccache/v3 v3.0.5 h1:hFX25+fxzNjsRlREYsoGNa2LoVEw5mPF8wkWq/UnevQ=
|
||||
github.com/karlseguin/ccache/v3 v3.0.5/go.mod h1:qxC372+Qn+IBj8Pe3KvGjHPj0sWwEF7AeZVhsNPZ6uY=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs=
|
||||
github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
@@ -661,12 +660,12 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66 h1:pAYrdyIKxPsMs/nRcTEnS9za2io11g7Rt7ng7HK82hk=
|
||||
github.com/openfga/api/proto v0.0.0-20240906203051-102620ef2a66/go.mod h1:gil5LBD8tSdFQbUkCQdnXsoeU9kDJdJgbGdHkgJfcd0=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f h1:ZMZ7ntMnaHIPZxvVQv/aqC4ctzLqH+9Fqn4uw35kQpk=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20240926131254-992b301a003f/go.mod h1:ll/hN6kS4EE6B/7J/PbZqac9Nuv7ZHpI+Jfh36JLrbs=
|
||||
github.com/openfga/openfga v1.6.2 h1:tHBAgiCPomCZb3IH0CFqOpTDVDA/Xb8kG87oX4JCbXc=
|
||||
github.com/openfga/openfga v1.6.2/go.mod h1:jzbEpheazf6MFjtanQt1rpxexSRzfa9057F7JlkMv2I=
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5 h1:z9jaRoo+NIN1AB0ogjtrjx1316TTuq6IbqpEg3UJycA=
|
||||
github.com/openfga/api/proto v0.0.0-20250107154247-c22e6db5c4f5/go.mod h1:m74TNgnAAIJ03gfHcx+xaRWnr+IbQy3y/AVNwwCFrC0=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c h1:1y84C0V4NRfPtRi4MqQ7+gnFtYgeBKPIeIAPLdVJ7j4=
|
||||
github.com/openfga/language/pkg/go v0.2.0-beta.2.0.20241115164311-10e575c8e47c/go.mod h1:12RMe/HuRNyOzS33RQa53jwdcxE2znr8ycXMlVbgQN4=
|
||||
github.com/openfga/openfga v1.8.4 h1:OqyRpuxMCxcS7irTFYFkhAIYzmAnczNwxUqjnuZOQyo=
|
||||
github.com/openfga/openfga v1.8.4/go.mod h1:9Ax9VMMySV2JMsCT8MTePeYt4OrTnPAy1XUV1y9RyuU=
|
||||
github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w=
|
||||
github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
@@ -693,8 +692,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pressly/goose/v3 v3.22.1 h1:2zICEfr1O3yTP9BRZMGPj7qFxQ+ik6yeo+z1LMuioLc=
|
||||
github.com/pressly/goose/v3 v3.22.1/go.mod h1:xtMpbstWyCpyH+0cxLTMCENWBG+0CSxvTsXhW95d5eo=
|
||||
github.com/pressly/goose/v3 v3.24.0 h1:sFbNms7Bd++2VMq6HSgDHDLWa7kHz1qXzPb3ZIU72VU=
|
||||
github.com/pressly/goose/v3 v3.24.0/go.mod h1:rEWreU9uVtt0DHCyLzF9gRcWiiTF/V+528DV+4DORug=
|
||||
github.com/prometheus/alertmanager v0.27.0 h1:V6nTa2J5V4s8TG4C4HtrBP/WNSebCCTYGGv4qecA/+I=
|
||||
github.com/prometheus/alertmanager v0.27.0/go.mod h1:8Ia/R3urPmbzJ8OsdvmZvIprDwvwmYCmUbwBL+jlPOE=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
@@ -873,14 +872,14 @@ go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
|
||||
go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
|
||||
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4=
|
||||
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
@@ -1088,8 +1087,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU=
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484 h1:ChAdCYNQFDk5fYvFZMywKLIijG7TC2m1C2CMEu11G3o=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241216192217-9240e9c98484/go.mod h1:KRUmxRI4JmbpAm8gcZM4Jsffi859fo5LQjILwuqj9z8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4=
|
||||
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
@@ -1172,8 +1171,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM=
|
||||
modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8=
|
||||
modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
||||
@@ -2,16 +2,17 @@ package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/grafana/authlib/authn"
|
||||
authClaims "github.com/grafana/authlib/claims"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -27,10 +28,13 @@ const (
|
||||
// var _ interceptors.Authenticator = (*Authenticator)(nil)
|
||||
|
||||
type Authenticator struct {
|
||||
IDTokenVerifier authn.Verifier[authn.IDTokenClaims]
|
||||
Tracer tracing.Tracer
|
||||
}
|
||||
|
||||
func (f *Authenticator) Authenticate(ctx context.Context) (context.Context, error) {
|
||||
ctx, span := f.Tracer.Start(ctx, "legacy.grpc.Authenticator.Authenticate")
|
||||
defer span.End()
|
||||
|
||||
r, err := identity.GetRequester(ctx)
|
||||
if err == nil && r != nil {
|
||||
return ctx, nil // noop, requester exists
|
||||
@@ -38,16 +42,19 @@ func (f *Authenticator) Authenticate(ctx context.Context) (context.Context, erro
|
||||
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no metadata found")
|
||||
err := status.Error(codes.Unauthenticated, "no metadata found in grpc context")
|
||||
span.RecordError(err)
|
||||
return nil, err
|
||||
}
|
||||
user, err := f.decodeMetadata(ctx, md)
|
||||
user, err := f.decodeMetadata(md)
|
||||
if err != nil {
|
||||
span.RecordError(err)
|
||||
return nil, err
|
||||
}
|
||||
return identity.WithRequester(ctx, user), nil
|
||||
}
|
||||
|
||||
func (f *Authenticator) decodeMetadata(ctx context.Context, meta metadata.MD) (identity.Requester, error) {
|
||||
func (f *Authenticator) decodeMetadata(meta metadata.MD) (identity.Requester, error) {
|
||||
// Avoid NPE/panic with getting keys
|
||||
getter := func(key string) string {
|
||||
v := meta.Get(key)
|
||||
@@ -57,20 +64,10 @@ func (f *Authenticator) decodeMetadata(ctx context.Context, meta metadata.MD) (i
|
||||
return ""
|
||||
}
|
||||
|
||||
// First try the token
|
||||
token := getter(mdToken)
|
||||
if token != "" && f.IDTokenVerifier != nil {
|
||||
claims, err := f.IDTokenVerifier.Verify(ctx, token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Printf("TODO, convert CLAIMS to an identity %+v\n", claims)
|
||||
}
|
||||
|
||||
user := &identity.StaticRequester{}
|
||||
user.Login = getter(mdLogin)
|
||||
if user.Login == "" {
|
||||
return nil, fmt.Errorf("no login found in grpc metadata")
|
||||
return nil, status.Error(codes.Unauthenticated, "no login found in grpc metadata")
|
||||
}
|
||||
|
||||
// The namespaced versions have a "-" in the key
|
||||
@@ -80,34 +77,34 @@ func (f *Authenticator) decodeMetadata(ctx context.Context, meta metadata.MD) (i
|
||||
user.Type = authClaims.TypeUser
|
||||
user.UserID, err = strconv.ParseInt(getter("grafana-userid"), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid user id: %w", err)
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user id")
|
||||
}
|
||||
user.OrgID, err = strconv.ParseInt(getter("grafana-orgid"), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid org id: %w", err)
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid org id")
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
typ, id, err := authClaims.ParseTypeID(getter(mdUserID))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid user id: %w", err)
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user id")
|
||||
}
|
||||
user.Type = typ
|
||||
user.UserID, err = strconv.ParseInt(id, 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid user id: %w", err)
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user id")
|
||||
}
|
||||
|
||||
_, id, err = authClaims.ParseTypeID(getter(mdUserUID))
|
||||
_, uid, err := authClaims.ParseTypeID(getter(mdUserUID))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid user id: %w", err)
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid user uid")
|
||||
}
|
||||
user.UserUID = id
|
||||
user.UserUID = uid
|
||||
|
||||
user.OrgID, err = strconv.ParseInt(getter(mdOrgID), 10, 64)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid org id: %w", err)
|
||||
return nil, status.Error(codes.Unauthenticated, "invalid org id")
|
||||
}
|
||||
user.OrgRole = identity.RoleType(getter(mdOrgRole))
|
||||
return user, nil
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
)
|
||||
|
||||
func TestBasicEncodeDecode(t *testing.T) {
|
||||
@@ -20,10 +20,10 @@ func TestBasicEncodeDecode(t *testing.T) {
|
||||
OrgRole: identity.RoleAdmin,
|
||||
}
|
||||
|
||||
auth := &Authenticator{}
|
||||
auth := &Authenticator{Tracer: tracing.NewNoopTracerService()}
|
||||
|
||||
md := encodeIdentityInMetadata(before)
|
||||
after, err := auth.decodeMetadata(context.Background(), md)
|
||||
after, err := auth.decodeMetadata(md)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, before.GetID(), after.GetID())
|
||||
require.Equal(t, before.GetUID(), after.GetUID())
|
||||
|
||||
@@ -189,6 +189,11 @@ func DashboardBuilder(namespaced resource.NamespacedDocumentSupplier) (resource.
|
||||
Filterable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: DASHBOARD_LEGACY_ID,
|
||||
Type: resource.ResourceTableColumnDefinition_INT64,
|
||||
Description: "Deprecated legacy id of the dashboard",
|
||||
},
|
||||
})
|
||||
if namespaced == nil {
|
||||
namespaced = func(ctx context.Context, namespace string, blob resource.BlobSupport) (resource.DocumentBuilder, error) {
|
||||
@@ -267,6 +272,7 @@ func (s *DashboardDocumentBuilder) BuildDocument(ctx context.Context, key *resou
|
||||
|
||||
// metadata name is the dashboard uid
|
||||
summary.UID = obj.GetName()
|
||||
summary.ID = obj.GetDeprecatedInternalID() // nolint:staticcheck
|
||||
|
||||
doc := resource.NewIndexableDocument(key, rv, obj)
|
||||
doc.Title = summary.Title
|
||||
@@ -310,11 +316,9 @@ func (s *DashboardDocumentBuilder) BuildDocument(ctx context.Context, key *resou
|
||||
doc.Fields = map[string]any{
|
||||
DASHBOARD_SCHEMA_VERSION: summary.SchemaVersion,
|
||||
DASHBOARD_LINK_COUNT: summary.LinkCount,
|
||||
DASHBOARD_LEGACY_ID: summary.ID,
|
||||
}
|
||||
|
||||
if summary.ID > 0 {
|
||||
doc.Fields[DASHBOARD_LEGACY_ID] = summary.ID
|
||||
}
|
||||
if len(panelTypes) > 0 {
|
||||
sort.Strings(panelTypes)
|
||||
doc.Fields[DASHBOARD_PANEL_TYPES] = panelTypes
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"c"
|
||||
],
|
||||
"labels": {
|
||||
"grafana.app/deprecatedInternalID": "141",
|
||||
"host": "abc",
|
||||
"region": "xyz"
|
||||
},
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
},
|
||||
"labels": {
|
||||
"host": "abc",
|
||||
"region": "xyz"
|
||||
"region": "xyz",
|
||||
"grafana.app/deprecatedInternalID": "141"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
|
||||
@@ -168,6 +168,13 @@
|
||||
"format": "int64",
|
||||
"description": "Total number of views",
|
||||
"priority": 0
|
||||
},
|
||||
{
|
||||
"name": "legacy_id",
|
||||
"type": "number",
|
||||
"format": "int64",
|
||||
"description": "Deprecated legacy id of the dashboard",
|
||||
"priority": 0
|
||||
}
|
||||
],
|
||||
"rows": [
|
||||
@@ -198,6 +205,7 @@
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"object": {
|
||||
@@ -239,6 +247,7 @@
|
||||
100,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"object": {
|
||||
@@ -282,6 +291,7 @@
|
||||
50,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"object": {
|
||||
|
||||
@@ -80,7 +80,8 @@ func ProvideUnifiedStorageGrpcService(
|
||||
|
||||
// FIXME: This is a temporary solution while we are migrating to the new authn interceptor
|
||||
// grpcutils.NewGrpcAuthenticator should be used instead.
|
||||
authn, err := grpcutils.NewGrpcAuthenticatorWithFallback(cfg, reg, tracing, &grpc.Authenticator{})
|
||||
fallback := &grpc.Authenticator{Tracer: tracing}
|
||||
authn, err := grpcutils.NewGrpcAuthenticatorWithFallback(cfg, reg, tracing, fallback)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -398,6 +398,7 @@ func doFolderTests(t *testing.T, helper *apis.K8sTestHelper) *apis.K8sTestHelper
|
||||
"kind": "Folder",
|
||||
"metadata": {
|
||||
"creationTimestamp": "${creationTimestamp}",
|
||||
"labels": {"grafana.app/deprecatedInternalID":"1"},
|
||||
"name": "` + uid + `",
|
||||
"namespace": "default",
|
||||
"resourceVersion": "${resourceVersion}",
|
||||
|
||||
Loaded 100 of 150 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user